Language/React.js
[React] 감정일기장 프로젝트 : EditPage 구현하기
JJcoding
2024. 10. 29. 10:59
Edit Page 구현하기
- 컴포넌트 구조는
- Header 컴포넌트
- Editor 컴포넌트
Edit.jsx의 기능 중 존재하지 않는 페이지에 갔을 경우 코드를 이렇게 구현하게 된다면 에러가 발생한다.
const getCurrentDiaryItem = () => {
const currentDiaryItem = data.find(
(item) => String(item.id) === String(params.id)
);
if (!currentDiaryItem) {
window.alert("존재하지 않는 일기입니다람쥐");
**nav("/", { replace: true });**
}
return currentDiaryItem;
};
const currentDiaryItem = getCurrentDiaryItem();
You should call navigate() in a React.useEffect(),
not when your component is first rendered.
Error Component Stack
- useNavigate는 마운트 되고 난 이후에만 실행이 되는 함수이다.
- BrowserRouter를 통해 사용할 수 있는 훅인데, BrowserRouter도 렌더링이 되지 않은 상태 (모든 컴포넌트가 마운트 돼야 BrowserRouter 컴포넌트도 마운트 되는거니까) 에서 사용하려니까 당연히 안되는 것이다.
- useEffect를 사용해서 마운트되고 난 후 실행하면 된다. 아래 참고
Edit.jsx
import { useParams, useNavigate } from "react-router-dom";
import Header from "../components/Header";
import Button from "../components/Button";
import Editor from "../components/Editor";
import { useContext, useEffect, useState } from "react";
import { DiaryDispatchContext, DiaryStateContext } from "../App";
const Edit = () => {
const nav = useNavigate();
const params = useParams();
const { onDelete, onUpdate } = useContext(DiaryDispatchContext);
const data = useContext(DiaryStateContext);
const [curDiaryItem, setCurDiaryItem] = useState();
useEffect(() => {
const currentDiaryItem = data.find(
(item) => String(item.id) === String(params.id)
);
if (!currentDiaryItem) {
window.alert("존재하지 않는 일기입니다람쥐");
nav("/", { replace: true });
}
setCurDiaryItem(currentDiaryItem);
}, [params.id, data]);
const onClickDelete = () => {
if (
window.confirm("일기를 정말 삭제할까용가리? 다시 복구되지 않습니다람쥐")
) {
// 확인
onDelete(params.id);
nav("/", { replace: true });
}
};
const onSubmit = (input) => {
if (window.confirm("일기를 정말 수정할까용가리?")) {
onUpdate(
params.id,
input.createdDate.getTime(),
input.emotionId,
input.content
);
nav("/", { replace: true });
}
};
return (
<div>
<Header
title={"일기 수정하기"}
leftChild={<Button onClick={() => nav(-1)} text={"< 뒤로 가기"} />}
rightChild={
<Button onClick={onClickDelete} text={"삭제하기"} type={"NEGATIVE"} />
}
/>
<Editor onSubmit={onSubmit} initData={curDiaryItem} />
</div>
);
};
export default Edit;
Editor.jsx
import "./Editor.css";
import EmotionItem from "./EmotionItem";
import Button from "./Button";
import { useState, useEffect } from "react";
import { useNavigate } from "react-router-dom";
...생략
useEffect(() => {
if (initData) {
setInput({
...initData,
createdDate: new Date(Number(initData.createdDate)),
});
}
}, [initData]);
...생략
- ‘수정하기’를 클릭했을 때 수정하려는 일기의 정보가 Edit 페이지에 이미 바인딩 되어있도록 설정하는 것
- 완성
출처 : 한입 크기로 잘라먹는 리액트