지난 번 만들어둔 props-drilling으로 만들어둔 프로젝트에 불편함을 느끼면서 context를 사용하여 불필요한 props-drilling을 제거해 코드를 리펙토링 하기로 했다.
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>
);
};
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;
PokemonContext.jsx파일에 필요한 로직들을 로드시키기 위해 다음과 같이 사용
const PokemonDetail = () => {
const { addPokemon } = usePokemon();
// parameter가져오기
useRef, useContext, useEffect 등 여러가지 훅들을 한번에 익히며 사용하려고 하다보니 아직 숙지가 잘 되지 않아서인지 혼동들이 있었고 provider을 로드 시키는 걸 까먹는다는지 이런 실수들이 있었다.
=> 여러번 반복하며 연습해야할 것 같다.