โจ Custom Hook ๊ฐ์ ๊ณผ์
1. ์ฒ์ ์์ฑํ Hook (์๋ชป๋ ๋ฒ์ )
const useLocalStorage = (initialState) => {
const getLocalStorage = (key) => {
try {
const item = window.localStorage.getItem(key);
return item ? JSON.parse(item) : initialState;
} catch (error) {
console.error(error);
}
};
const setLocalStorage = (key, data) => {
try {
if ((key, data)) window.localStorage.setItem(key, JSON.stringify(data));
} catch (error) {
console.error(error);
}
};
return [getLocalStorage, setLocalStorage];
};
2. ๊ฐ์ ๋ Hook (์ฌ๋ฐ๋ฅธ ๋ฒ์ )
const useLocalStorage = (key, initialState) => {
const [localStg, setLocalStg] = useState(() => {
try {
const item = window.localStorage.getItem(key);
return item ? JSON.parse(item) : initialState;
} catch (error) {
console.error(error);
return initialState;
}
});
useEffect(() => {
if (localStg !== undefined)
window.localStorage.setItem(key, JSON.stringify(localStg));
}, [key, localStg]);
return [localStg, setLocalStg];
};
๐ ๋ฌธ์ ๋ฐ๊ฒฌ๊ณผ ํด๊ฒฐ ๊ณผ์
1. ์ฒซ ์๋: Add ๋ก์ง์์ ์ง์ localStorage ์ค์
const addHandler = (e) => {
e.stopPropagation();
if (selectedPokemon.some((e) => e.id === pokemon.id)) {
return toast.warn("๊ฐ์ ํฌ์ผ๋ชฌ์ ์ถ๊ฐํ ์ ์์ต๋๋ค.๐");
}
if (selectedIdx >= 6) {
return toast.error("๋ ์ด์ ์ ํํ ์ ์์ต๋๋ค.๐");
}
dispatch(addPokemon({ ...pokemon }));
setLocalStg(selectedPokemon)
toast.success(`์์ธ!! "${pokemon.korean_name}"์(๋ฅผ) ์ก์๋ค!๐ช`);
};

2. ๋ฐ๊ฒฌํ ๋ฌธ์ ์
- useState์ ๋น๋๊ธฐ์ ํน์ฑ์ผ๋ก ์ธํด ์ฆ์ ๊ฐ์ด ๋ฐ์๋์ง ์์
- localStorage์ ๊ธฐ๋ณธ๊ฐ๋ง ์ ์ฅ๋๊ณ ์ค์ ๋ฐ์ดํฐ๋ ์ ์ฅ๋์ง ์์
3. ์ต์ข
ํด๊ฒฐ์ฑ
const [, setLocalStg] = useLocalStorage('selectedPokemon', []);
useEffect(() => {
setLocalStg(selectedPokemon)
}, [selectedPokemon, setLocalStg])
๐ก ํํฐ๋๊ณผ์ ๋ฉด๋ด์์ ์ป์ ์ธ์ฌ์ดํธ
1. ๋ก์ปฌ ์คํ ๋ฆฌ์ง ๊ด๋ฆฌ ๋ฐฉ์
- Q: "๋ก์ปฌ ์คํ ๋ฆฌ์ง๋ฅผ ํ
์ผ๋ก ๊ด๋ฆฌํ๋ ๊ฒ ์ผ๋ฐ์ ์ธ๊ฐ์?"
- A: "๋ค, ๋งค์ฐ ์ผ๋ฐ์ ์ธ ํจํด์
๋๋ค."
- ๋ฆฌ๋์๋ ์์ ํจ์์ฌ์ผ ํ๋ฏ๋ก ๋ธ๋ผ์ฐ์ API ํธ์ถ์ด ์ด๋ ค์
- ์ฌ์ด๋ ์ดํํธ(useEffect ๋ฑ)๋ ์ปค์คํ
ํ
์์ ์ฒ๋ฆฌํ๋ ๊ฒ์ด ์ข์
2. Custom Hook vs Redux
- Q: ๋ฆฌ๋์ค๋ฅผ ์ฌ์ฉํ ๋ ์ปค์คํ
ํ
์ ์ธ์ ํ์ฉํ๋ ๊ฒ ์ข์๊น์?
- A: ์ ์ญ ์ํ ๊ด๋ฆฌ๊ฐ ํ์ ์์ ๋
โ ์ฆ, ํน์ ์ปดํฌ๋ํธ ๋ด๋ถ์์๋ง ํ์ํ ์ํ๋ผ๋ฉด ๊ตณ์ด ๋ฆฌ๋์ค๋ฅผ ์ฌ์ฉํ ํ์๊ฐ ์์.
- Custom Hook ์ฌ์ฉ ์ผ์ด์ค:
- ๋ธ๋ผ์ฐ์ API ์ฐ๋
- ์ปดํฌ๋ํธ ํนํ ๋ก์ง
- ์ฌ์ฌ์ฉ ๊ฐ๋ฅํ ๋ก์ง
- Redux ์ฌ์ฉ ์ผ์ด์ค:
- ๋ณต์กํ ์ ์ญ ์ํ ๊ด๋ฆฌ
- ์์ธก ๊ฐ๋ฅํ ์ํ ํ๋ฆ ํ์ ์
- ๋๊ท๋ชจ ์ ํ๋ฆฌ์ผ์ด์
3. ํ๋์ ์ํ ๊ด๋ฆฌ ํธ๋ ๋
- Q: "ํน์ ๊ทธ๋ฌ๋ฉด.. ์ค๋ฌด์์ ๋ง์ด ์ ํธํ์๋ ์ํ๊ด๋ฆฌ๋ ์ด๋ค๊ฑด๊ฐ์?"
- A: "์ ๊ท ํ๋ก์ ํธ๋ฅผ ๋ง๋ค๋๋ ๋ฆฌ๋์ค๋ฅผ ์ ์์ฐ๋ ์ถ์ธ์
๋๋ค. ๋์ฒด ๊ธฐ์ ๋ก Zustand๋ก ๋ง์ด ์ฐ์ด๋๊ฒ ๊ฐ์์"
- ๋ฆฌ๋์ค์ ์ฌ์ฉ ๋น๋๊ฐ ์ค์ด๋๋ ์ถ์ธ
- ์๋ก์ด ๋์๋ค์ด ๋ถ์
- React Query: ์๋ฒ ์ํ ๊ด๋ฆฌ
- Zustand: ๊ฐ๋จํ ํด๋ผ์ด์ธํธ ์ํ ๊ด๋ฆฌ
- "ํ์ํ ๋งํผ๋ง" ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ฌ์ฉํ๋ ๊ฒ์ด ํธ๋ ๋
๐ฏ ์ค๋ฌด์ Best Practice
-
์ํ ๊ด๋ฆฌ ๋๊ตฌ ์ ํ ๊ธฐ์ค
- ํ๋ก์ ํธ ๊ท๋ชจ
- ํ์ ์น์๋
- ์ ์ง๋ณด์ ์ฉ์ด์ฑ
-
๋ก์ปฌ ์คํ ๋ฆฌ์ง ๊ด๋ฆฌ
- Custom Hook์ผ๋ก ๋ถ๋ฆฌ
- useEffect๋ก ๋๊ธฐํ
- ์๋ฌ ์ฒ๋ฆฌ ํฌํจ
-
์ฝ๋ ๊ตฌ์กฐํ
- ๊ด์ฌ์ฌ ๋ถ๋ฆฌ
- ์ฌ์ฌ์ฉ์ฑ ๊ณ ๋ ค
- ํ
์คํธ ์ฉ์ด์ฑ
โญ๏ธ ํต์ฌ ๋ฐฐ์ด ์
- Custom Hook์ผ๋ก ๋ธ๋ผ์ฐ์ API ๊ด๋ฆฌํ๋ ๊ฒ์ด ๋ฒ ์คํธ ํ๋ํฐ์ค
- useState์ ๋น๋๊ธฐ์ ํน์ฑ ์ดํด์ ์ค์์ฑ
- useEffect๋ฅผ ํตํ ์ ์ ํ ๋๊ธฐํ์ ํ์์ฑ
- ํ๋ ์น ๊ฐ๋ฐ์์์ ์ํ ๊ด๋ฆฌ ํธ๋ ๋ ๋ณํ
๐ ์์ผ๋ก์ ํ์ต ๋ฐฉํฅ
- React Query, Zustand ๋ฑ ๋ชจ๋ ์ํ ๊ด๋ฆฌ ๋๊ตฌ ํ์ต
- Custom Hook ๋์์ธ ํจํด ์ฌํ ํ์ต