[Udemy] React 실전(감정일기장) - 프로젝트 기초공사2

productuidev·2022년 5월 18일
0

React Study

목록 보기
39/52
post-thumbnail
post-custom-banner

React 실전 (Project)

Udemy - 한입크기로 잘라 먹는 리액트


📌 감정일기장 만들기 프로젝트 기초공사2

이전 챕터 복습

☑️ 1. 상태관리 설정

App 컴포넌트가 ReactRouter가 제공하는 BrowserRouter 컴포넌트로 현재 4개의 페이지를 자식요소로 두고 있음
실시간으로 URL 경로에 따라서 매핑
4개의 페이지는 각각 일기 데이터 state에 각각 다른 부분을 필요로 함

  • Home : 일기 리스트
  • Create New : 일기 생성 로직
  • Update Edit : 일기 수정 로직
  • Read Diary : 일기 하나의 데이터

일기 데이터를 관리할 수 있는 state를 만들고 관리할 수 있는 기능 만들기

☑️ 2. 프로젝트 State Context 설정

일기 데이터 state를 공급할 Context를 생성하고 Provider로 data 공급

☑️ 3. 프로젝트 Dispatch Context 설정

일기 데이터 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;
profile
필요한 내용을 공부하고 저장합니다.
post-custom-banner

0개의 댓글