이전 챕터 복습
App 컴포넌트가 ReactRouter가 제공하는 BrowserRouter 컴포넌트로 현재 4개의 페이지를 자식요소로 두고 있음
실시간으로 URL 경로에 따라서 매핑
4개의 페이지는 각각 일기 데이터 state에 각각 다른 부분을 필요로 함
Create
New : 일기 생성 로직 Update
Edit : 일기 수정 로직 Read
Diary : 일기 하나의 데이터일기 데이터를 관리할 수 있는 state를 만들고 관리할 수 있는 기능 만들기
일기 데이터 state를 공급할 Context를 생성하고 Provider로 data 공급
일기 데이터 state의 Dispatch 함수들을 공급할 Context를 생성하고 Provider로 onCreate, onRemove, onEdit 함수 공급
src/App.js
import React, { useReducer, useRef } from "react";
import "./App.css";
import { BrowserRouter, Route, Routes } from "react-router-dom";
import Home from "./pages/Home";
import New from "./pages/New";
import Edit from "./pages/Edit";
import Diary from "./pages/Diary";
// 2개의 파라미터 (state, action)
const reducer = (state, action) => {
let newState = [];
switch(action.type){
case "INIT" : {
return action.data;
}
case "CREATE" : {
// const newItem = { ...action.data };
newState = [action.data, ...state]; // 변경될 값
break;
}
case "REMOVE" : {
newState = state.filter((it)=>it.id !== action.targetId);
break;
}
case "EDIT" : {
newState = state.map((it)=>it.id === action.data.id ? {...action.data} : it);
break;
}
default:
return state;
}
return newState;
};
// Context API
export const DiaryStateContext = React.createContext();
export const DiaryDispatchContext = React.createContext();
function App() {
// data의 기본 state는 []
const [data, dispatch] = useReducer(reducer, []);
// 일기 id로 사용
const dataId = useRef(0);
// CREATE
const onCreate = (date, content, emotion) => {
dispatch({
type : "CREATE",
data : {
id: dataId.current,
date : new Date(date).getTime(),
content,
emotion,
}
});
dataId.current += 1;
}
// REMOVE
const onRemove = (targetId) => {
dispatch({type: "REMOVE", targetId});
};
// EDIT
const onEdit = (targetId, date, content, emotion) => {
dispatch({
type : "EDIT",
data : {
id : targetId,
date : new Date(date).getTime(),
content,
emotion,
}
});
};
return (
<DiaryStateContext.Provider value={data}>
<DiaryDispatchContext.Provider value={{onCreate, onEdit, onRemove}}>
<BrowserRouter>
<div className="App">
<h2>App.js</h2>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/new" element={<New />} />
<Route path="/edit" element={<Edit />} />
<Route path="/diary/:id" element={<Diary />} />
</Routes>
</div>
</BrowserRouter>
</DiaryDispatchContext.Provider>
</DiaryStateContext.Provider>
);
}
export default App;