Day28_개인프로젝트 포켓몬도감 만들기(React 리펙토링 with context)

정소현·2024년 8월 24일
0

스파르타

목록 보기
35/50

🌟 React context를 활용한 리펙토링

지난 번 만들어둔 props-drilling으로 만들어둔 프로젝트에 불편함을 느끼면서 context를 사용하여 불필요한 props-drilling을 제거해 코드를 리펙토링 하기로 했다.

  1. src > contexts폴더를 생성, PokemonContext.jsx 파일을 만듬
  2. PokemonContext.js 파일에 createContext를 한 후 Dex.jsx에 있었던 재사용이 필요한 코드들을 옮겨와 로직들을 작성
  3. PokemonProvider을 최상위파일(App.jsx)에서 감싸주고
  4. 로직들이 필요한 곳에서 usePokemon 을 import해 사용

PokemonContext.jsx

import { createContext, useState, useContext } from "react";

const PokemonContext = createContext();

export const usePokemon = () => {
  return useContext(PokemonContext);
};

export const PokemonProvider = ({ children }) => {
  const [selectPokemon, setSelectPokemon] = useState([]);
  const addPokemon = (addPokemon) => {
    if (selectPokemon.length >= 6) {
      alert("포켓몬은 최대 6개까지만 추가가 가능합니다 삭제 후 추가해주세요");
    } else if (
      selectPokemon.find((prevPokemon) => prevPokemon.id === addPokemon.id)
    ) {
      alert("이미 추가되어있는 포켓몬입니다.");
    } else {
      setSelectPokemon((prevPokemon) => [...prevPokemon, addPokemon]);
    }
  };

  const removePokemon = (removePokemon) => {
    setSelectPokemon((prevPokemon) =>
      prevPokemon.filter((prevPokemon) => prevPokemon.id !== removePokemon.id)
    );
  };

  return (
    <PokemonContext.Provider
      value={{ selectPokemon, addPokemon, removePokemon }}
    >
      {children}
    </PokemonContext.Provider>
  );
};

App.jsx

import React from "react";
import Home from "./pages/Home";
import Dex from "./pages/Dex";
import PokemonDetail from "./pages/PokemonDetail";
import { Route, BrowserRouter, Routes } from "react-router-dom";
import GlobalStyle from "./styles/GlobalStyle";
import GlobalFont from "./styles/GlobalFont";
import { PokemonProvider } from "./contexts/PokemonContext";

const App = () => {
  return (
    <>
      <GlobalStyle />
      <GlobalFont />

      <BrowserRouter>
        <PokemonProvider>
          <Routes>
            <Route path="/" element={<Home />}></Route>
            <Route path="/Dex" element={<Dex />}></Route>
            <Route
              path="/PokemonDetail/:id"
              element={<PokemonDetail />}
            ></Route>
          </Routes>
        </PokemonProvider>
      </BrowserRouter>
    </>
  );
};

export default App;

PokemonDetail.jsx

PokemonContext.jsx파일에 필요한 로직들을 로드시키기 위해 다음과 같이 사용

const PokemonDetail = () => {
  const { addPokemon } = usePokemon();
  // parameter가져오기

😱 어려웠던 점

useRef, useContext, useEffect 등 여러가지 훅들을 한번에 익히며 사용하려고 하다보니 아직 숙지가 잘 되지 않아서인지 혼동들이 있었고 provider을 로드 시키는 걸 까먹는다는지 이런 실수들이 있었다.
=> 여러번 반복하며 연습해야할 것 같다.

0개의 댓글