수정
을 하려면?! 원본일기의 데이터
가 있어야원본일기의 데이터를 가져오기
(App 컴포넌트의 date state) : useContext컴포넌트가 mount된 시점에 데이터 가져오기
DiaryEditor 컴포넌트
에 원본데이터 받기src/pages/Edit.js
import { useContext, useEffect, useState } from "react";
import { useNavigate, useParams } from "react-router-dom";
import { DiaryStateContext } from "../App";
import DiaryEditor from "../components/DiaryEditor";
const Edit = () => {
const [originData, setOriginData] = useState();
const navigate = useNavigate();
const {id} = useParams(); // 현재 전달받은 id
const diaryList = useContext(DiaryStateContext);
// console.log(id); // id 출력
// console.log(diaryList); // 5개의 원본데이터 출력
// 데이터는 컴포넌트가 mount된 시점에서 가져온다
// 조건 : 일기데이터가 1개라도 있을 때만 가져온다 (id 오류 방지 형변환)
// deps : id나 diaryList가 변할 때만 가져온다
useEffect(()=>{
if(diaryList.length>=1){
const targetDiary = diaryList.find((it)=>parseInt(it.id) === parseInt(id));
// console.log(targetDiary); // 가져온 id의 일기데이터 출력
// 조건 : id가 있을 때 setOriginData로 전달
// 조건 : 경로에 id가 잘못 전달되었을 때 홈으로 (뒤로가기 방지)
if(targetDiary) {
setOriginData(targetDiary);
}
else {
navigate('/', {replace:true});
}
}
},[id, diaryList, navigate]);
// targetDiary를 통해서 originData의 state를 저장해놓고
// originData가 있으면, DiaryEditor를 렌더링
// prop으로 원본데이터를 전달해주자 (isEdit, originData)
return (
<div>
{originData && <DiaryEditor isEdit={true} originData={originData} />}
</div>
);
}
export default Edit;
onEdit
공급 (+confirm 조건 추가)src/components/DiaryEditor.js
import { useState, useRef, useContext, useEffect } from "react";
import { useNavigate } from "react-router-dom";
import { DiaryDispatchContext } from "./../App";
import MyHeader from "./MyHeader";
import MyButton from "./MyButton";
import EmotionItem from "./EmotionItem";
const env = process.env;
env.PUBLIC_URL = env.PUBLIC_URL || "";
const emotionList = [
{
emotion_id : 1,
emotion_img : process.env.PUBLIC_URL + `/assets/emotion1.png`,
emotion_descript : '완전 좋음'
},
{
emotion_id : 2,
emotion_img : process.env.PUBLIC_URL + `/assets/emotion2.png`,
emotion_descript : '좋음'
},
{
emotion_id : 3,
emotion_img : process.env.PUBLIC_URL + `/assets/emotion3.png`,
emotion_descript : '그럭저럭'
},
{
emotion_id : 4,
emotion_img : process.env.PUBLIC_URL + `/assets/emotion4.png`,
emotion_descript : '나쁨'
},
{
emotion_id : 5,
emotion_img : process.env.PUBLIC_URL + `/assets/emotion5.png`,
emotion_descript : '끔찍함'
},
]
const getStringDate = (date) => {
return date.toISOString().slice(0, 10);
};
// DiaryEditor 함수에 isEdit, originData prop 넣어주기
const DiaryEditor = ({isEdit, originData}) => {
const [emotion, setEmotion] = useState(3); // 3번 default
const [date, setDate] = useState(getStringDate(new Date()));
const [content, setContent] = useState();
const contentRef = useRef();
const handleClickEmote = (emotion) => {
setEmotion(emotion);
};
// 작성완료에 onEdit 공급
const {onCreate, onEdit} = useContext(DiaryDispatchContext);
const handleSubmit = () => {
if(content.length < 1) {
contentRef.current.focus();
return;
}
// 작성완료 confirm 조건 추가 (새 일기 작성/수정 시)
// 조건에 따라 수정/작성 완료 후 alert창으로 묻기
if(window.confirm(isEdit ? "일기를 수정하시겠습니까?" : "새로운 일기를 작성하시겠습니까?")){
// 새 일기 작성인 경우(수정이 아닌 경우)
if(!isEdit) {
onCreate(date, content, emotion);
}
// 수정중인 경우 (onEdit의 props : 원본 id, 날짜, 내용, 감정)
else {
onEdit(originData.id, date, content, emotion);
}
};
navigate('/', {replace:true});
};
// useEffect deps(isEdit, originData)가 바뀌면 원본데이터 받아오기
// EditPage에서 렌더링하는 DiaryEditor에서만 useEffect가 동작하도록
// 캘린더 setDate 당일 날짜, 원본 감정, 원본 내용
useEffect(()=>{
if(isEdit) {
setDate(getStringDate(new Date(parseInt(originData.date))));
setEmotion(originData.emotion);
setContent(originData.content);
}
},[isEdit, originData]);
const navigate = useNavigate();
return (
<div className="DiaryEditor">
{/* 제목 표시 조건 */}
<MyHeader
headText={isEdit ? "일기 수정하기" : "새 일기쓰기"}
leftChild={<MyButton text={"< 뒤로가기"} onClick={()=>navigate(-1)} />}
/>
<div>
<section>
<h4>오늘은 언제인가요?</h4>
<div className="inputBox">
<input
className="inputDate"
type="date"
value={date}
onChange={(e)=>setDate(e.target.value)} />
</div>
</section>
<section>
<h4>오늘의 감정</h4>
<div className="inputBox emotionListWrapper">
{emotionList.map((it)=>(
<EmotionItem key={it.emotion_id} {...it} onClick={handleClickEmote} isSelected={it.emotion_id === emotion} />
// <div key={it.emotion_id}>{it.emotion_descript}</div>
))}
</div>
</section>
<section>
<h4>오늘의 일기</h4>
<div className="inputBox textWrapper">
<textarea
placeholder="오늘은 어땠나요?"
ref={contentRef}
value={content}
onChange={(e)=>setContent(e.target.value)}
/>
</div>
</section>
<section>
<div className="controlBox">
<MyButton text={"취소하기"} onClick={()=>navigate(-1)} />
<MyButton text={"작성완료"} type={"positive"} onClick={handleSubmit} />
</div>
</section>
</div>
</div>
);
};
export default DiaryEditor;
💬 얼마남지 않았어 😀🙂