No routes matched location "/edit/3"// App.js
return (
<DiaryStateContext.Provider value={data}>
<DiaryDispatchContext.Provider value={{ onCreate, onEdit, onRemove }}>
<BrowserRouter>
<div className="App">
<Routes>
<Route path="/" element={<Home />} />
<Route path="/new" element={<New />} />
// edit 컴포넌트에서도 path variable 설정해서 edit/1 과 같이 이동할 수 있도록 설정
<Route path="/edit/:id" element={<Edit />} />
<Route path="/diary/:id" element={<Diary />} />
</Routes>
</div>
</BrowserRouter>
</DiaryDispatchContext.Provider>
</DiaryStateContext.Provider>
);
// Edit.js
import { useNavigate, useParams } from "react-router-dom";
const Edit = () => {
const navigate = useNavigate();
// 현재 전달받은 id 꺼내기
const { id } = useParams();
console.log(id);
return (
<div>
<h1>Edit</h1>
</div>
);
};
export default Edit;

useContext 사용하여 컨텍스트로부터 데이터 받아오기// Edit.js
import { useNavigate, useParams } from "react-router-dom";
import { useContext } from "react";
import { DiaryStateContext } from "../App";
const Edit = () => {
const navigate = useNavigate();
// 현재 전달받은 id 꺼내기
const { id } = useParams();
const diaryList = useContext(DiaryStateContext);
console.log(diaryList);
return (
<div>
<h1>Edit</h1>
</div>
);
};
export default Edit;

(2) 수정할 id값과 동일한 일기 데이터 가져오기
// Edit.js
import { useNavigate, useParams } from "react-router-dom";
import { useContext, useEffect } from "react";
import { DiaryStateContext } from "../App";
const Edit = () => {
const navigate = useNavigate();
// 현재 전달받은 id 꺼내기
const { id } = useParams();
const diaryList = useContext(DiaryStateContext);
console.log(diaryList);
// edit 컴포넌트가 mount 되었을 때 수정하려는 일기데이터 가져오기
// id가 변하거나 diaryList가 변할때만 일기 데이터 꺼내오기
useEffect(() => {
if (diaryList.length >= 1) {
const targetDiary = diaryList.find(
// target의 id와 수정페이지의 id가 동일하도록 Int로 변경해줌
(it) => parseInt(it.id) === parseInt(id)
);
console.log(targetDiary);
}
}, [id, diaryList]);
return (
<div>
<h1>Edit</h1>
</div>
);
};
export default Edit;

만약, 존재하지 않는 id를 호출할경우

동일하게 edit 페이지가 뜨는데, 이는 잘못된 접근이기 때문에 home으로 돌려보내야함
// Edit.js
useEffect(() => {
if (diaryList.length >= 1) {
const targetDiary = diaryList.find(
// target의 id와 수정페이지의 id가 동일하도록 Int로 변경해줌
(it) => parseInt(it.id) === parseInt(id)
);
console.log(targetDiary);
if (!targetDiary) {
// 존재하지 않는 id를 불러올 경우 undefined(falsy)한 값으로 인식
navigate("/", { replace: true });
}
}
}, [id, diaryList]);
// Edit.js
// target Diary Data 저장
const [originData, setOriginData] = useState();
useEffect(() => {
if (diaryList.length >= 1) {
const targetDiary = diaryList.find(
// target의 id와 수정페이지의 id가 동일하도록 Int로 변경해줌
(it) => parseInt(it.id) === parseInt(id)
);
console.log(targetDiary);
if (targetDiary) {
setOriginData(targetDiary);
} else {
// 존재하지 않는 id를 불러올 경우 undefined(falsy)한 값으로 인식
navigate("/", { replace: true });
}
}
}, [id, diaryList]);

// Edit.js
const Edit = () => {
const navigate = useNavigate();
// 현재 전달받은 id 꺼내기
const { id } = useParams();
const diaryList = useContext(DiaryStateContext);
// target Diary Data 저장
const [originData, setOriginData] = useState();
// edit 컴포넌트가 mount 되었을 때 수정하려는 일기데이터 가져오기
// id가 변하거나 diaryList가 변할때만 일기 데이터 꺼내오기
useEffect(() => {
if (diaryList.length >= 1) {
const targetDiary = diaryList.find(
// target의 id와 수정페이지의 id가 동일하도록 Int로 변경해줌
(it) => parseInt(it.id) === parseInt(id)
);
console.log(targetDiary);
if (targetDiary) {
setOriginData(targetDiary);
} else {
// 존재하지 않는 id를 불러올 경우 undefined(falsy)한 값으로 인식
navigate("/", { replace: true });
}
}
}, [id, diaryList]);
// originData가 있으면 DiaryEditor을 return함
return <div>{originData && <DiaryEditor />}</div>;
};
// 원래 있던 return <div></div>는 삭제
export default Edit;
// Edit.js
// originData가 있으면 DiaryEditor을 return함
return (
<div>
{/* Diary 컴포넌트에서는 isEdit과 originData를 받아서 수정폼으로 변환시켜줌 */}
{originData && <DiaryEditor isEdit={true} originData={originData} />}
</div>
);
// App.js
// Edit.js 에서 넘겨준 props 받기
const DiaryEditor = ({isEdit, originData}) => {
// edit페이지에서 DiaryComponent를 랜더하면 isEdit과 originData가 변경됨 -> 이 때만 실행
useEffect(() => {
if (isEdit) {
// 원래 작성된 데이터로 변경
setDate(getStringDate(new Date(parseInt(originData.date))));
setslctEmotionId(originData.emotion);
setContent(originData.content);
}
}, [isEdit, originData]);
return (
<div>
{/* 1. header */}
<MyHeader
// isEdit === true 면 헤더text 수정
headText={isEdit ? "일기 수정하기" : "새 일기쓰기"}
leftChild={
<MyButton text={"< 뒤로가기"} onClick={() => navigate(-1)}></MyButton>
}
...
)
}

const DiaryEditor = ({ isEdit, originData }) => {
// onEdit 디스패치 함수도 불러오기
const { onCreate, onEdit } = useContext(DiaryDispatchContext);
// 작성완료 함수
const handleSubmit = () => {
if (content.length < 1) {
contentRef.current.focus();
return;
}
if (
window.confirm(
isEdit ? "일기를 수정할까요?" : "새로운 일기를 추가할까요?"
)
) {
// 수정이 아닐 경우 onCrate 실행
if (!isEdit) {
onCreate(date, content, slctEmotionId);
} else {
// 수정일 경우 onEdit 실행
onEdit(originData.id, date, content, slctEmotionId);
}
}
navigate("/", { replace: true });
};
return (
<div>
{/* 1. header */}
<MyHeader
// isEdit === true 면 헤더text 수정
headText={isEdit ? "일기 수정하기" : "새 일기쓰기"}
leftChild={
<MyButton text={"< 뒤로가기"} onClick={() => navigate(-1)}></MyButton>
}
></MyHeader>
...
<section>
<div className="control_box">
<MyButton text={"취소하기"} onClick={() => navigate(-1)} />
// isEdit에 따라 버튼명 수정
<MyButton
text={isEdit ? "수정하기" : "작성 완료"}
type={"positive"}
onClick={handleSubmit}
/>
</div>
</section>
</div>
</div>
);
}
