06. ๐ง ์ํ ๊ด๋ฆฌ ๋๊ตฌ์ ์ฒ ํ๊ณผ ์ต์ ํ ์ ๋ต
๐ ๊ฐ์
Context API๋ถํฐ Zustand, Jotai๊น์ง, ๋ค์ํ ์ํ ๊ด๋ฆฌ ๋๊ตฌ์ ์ฒ ํ์ ์ดํดํ๊ณ ์ํฉ์ ๋ง๋ ์ต์ ์ ์ ๋ต์ ์ ํํฉ๋๋ค.
๐ ์ด ๋ฉด์ ํญ๋ชฉ์ ๋ชฉํ
โฑ๏ธ ์์ ์ฝ๊ธฐ ์๊ฐ: 23๋ถ (ํต์ฌ ์์ฝ: 11๋ถ)
๐บ๏ธ ์ด ์ฑํฐ์ ํ๋ฆ
[๊ฐ๋
์ฌ์ ] โ [์ง๋ฌธ 1: Context API vs ๋ผ์ด๋ธ๋ฌ๋ฆฌ] โ [์ง๋ฌธ 2: Flux ์ํคํ
์ฒ] โ [์ค์ ๋ณํ ์ง๋ฌธ]
๐ฏ ์ด ์ฑํฐ๋ฅผ ๋ค ์ฝ์ผ๋ฉด ํ ์ ์๋ ๊ฒ
- Context API์ ์ฑ๋ฅ ํ๊ณ์ ์ ์ญ ์ํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ๋์ ์์ ์ ๋ช ํํ ๊ตฌ๋ถํฉ๋๋ค.
- Zustand(Flux)์ Jotai(Atomic)์ ํจ๋ฌ๋ค์ ์ฐจ์ด๋ฅผ ๊ธฐ์ ์ ์ผ๋ก ๋น๊ตํฉ๋๋ค.
- ๋ถํ์ํ ๋ฆฌ๋ ๋๋ง์ ๋ฐฉ์งํ๋ 'Selector' ์ต์ ํ ์๋ฆฌ๋ฅผ ์ค๋ช ํฉ๋๋ค.
๐ ํต์ฌ ๊ฐ๋ ์ฌ์ (Concept Glossary)
1. Props Drilling
์ปดํฌ๋ํธ ํธ๋ฆฌ ์๋จ์์ ํ๋จ์ผ๋ก ๋ฐ์ดํฐ๋ฅผ ์ ๋ฌํ๊ธฐ ์ํด, ์ค๊ฐ ์ปดํฌ๋ํธ๋ค์ด ์ฌ์ฉํ์ง๋ ์๋ Props๋ฅผ ๋จ์ํ ์ ๋ฌ๋ง ํ๋ ํ์์ ๋๋ค. ์ฝ๋์ ๊ฐ๋ ์ฑ๊ณผ ์ ์ง๋ณด์์ฑ์ ํฌ๊ฒ ํด์นฉ๋๋ค.
2. Flux ์ํคํ ์ฒ
๋ฐ์ดํฐ๊ฐ ํ ๋ฐฉํฅ์ผ๋ก๋ง ํ๋ฅด๋๋ก ๊ฐ์ ํ๋ ๋์์ธ ํจํด์
๋๋ค. Action โ Dispatcher โ Store โ View ์์ผ๋ก ๋ฐ์ดํฐ๊ฐ ํ๋ฅด๋ฉฐ, ์์ธก ๊ฐ๋ฅํ ์ํ ์
๋ฐ์ดํธ๋ฅผ ๊ฐ๋ฅํ๊ฒ ํฉ๋๋ค. (Redux, Zustand์ ๊ทผ๊ฐ)
3. ์์์ ์ํ (Atomic State)
๊ฑฐ๋ํ ํ๋์ ์์ (Store) ๋์ , ์์ ๋จ์์ ์ํ(Atom)๋ค์ ๋ ๋ฆฝ์ ์ผ๋ก ์ ์ํ๊ณ ์กฐํฉํ๋ ๋ฐฉ์์ ๋๋ค. ํ์ํ ์ปดํฌ๋ํธ๋ง ํด๋น Atom์ ๊ตฌ๋ ํ๋ฏ๋ก ๋ฆฌ๋ ๋๋ง ์ต์ ํ์ ์ ๋ฆฌํฉ๋๋ค. (Jotai, Recoil)
๐บ๏ธ ์ด ๋ฌธ์์ ๋ฐฐ๊ฒฝ ์ธ๊ณ๊ด: '์์๋ค ์ปค๋ฎค๋ํฐ'
- ๐ฃ ์์ฒ ( ์ ์ ): "์ํธ ๋! '์์๋ค ํ ๋ง ์ค์ ' ํ๋ ๋ฐ๊พธ๋๋ฐ ์ ์ฒด ํ์ด์ง๊ฐ ๋ค ๋ฆฌ๋ ๋๋ง๋ผ์. Context API ์ต๊ณ ๋ผ๋ฉด์์! ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ ์จ๋ ๋๋ค๋ฉด์์! ๐ญ"
- ๐ฆ ์ํธ ( ๋ฆฌ๋ ): "์์ฒ ๋, Context API๋ '์ํ ๊ด๋ฆฌ' ๋๊ตฌ๊ฐ ์๋๋ผ '์์กด์ฑ ์ฃผ์ ' ๋๊ตฌ์ ๋๋ค. ์ ์ญ์ ์ผ๋ก ๊ฐ์ ๊ณต์ ํ๋ ๋ฐ๋ ์ข์ง๋ง, ๋น๋ฒํ๊ฒ ๋ฐ๋๋ ๋ฐ์ดํฐ์๋ ์ฅ์ฝ์ด์ฃ . ๋๊ตฌ์ ์ด๋ฆ๋ณด๋ค ๊ทธ ๋๊ตฌ๊ฐ ํด๊ฒฐํ๋ ค๋ '์ง์ง ๋ฌธ์ '๋ฅผ ๋ณด์ธ์."
Q1. Context API์ ์ ์ญ ์ํ ๊ด๋ฆฌ ๋ผ์ด๋ธ๋ฌ๋ฆฌ(Zustand, Jotai ๋ฑ)์ ๊ทผ๋ณธ์ ์ธ ์ฐจ์ด๋ ๋ฌด์์ธ๊ฐ์?
๐ฏ ์ถ์ ์๋
Context API๊ฐ ๋ง๋ฅ์ด ์๋์ ์ธ์งํ๊ณ ์๋์ง, ๊ทธ๋ฆฌ๊ณ ๋๊ท๋ชจ ์ ํ๋ฆฌ์ผ์ด์ ์์ ๋ฐ์ํ๋ ๋ฆฌ๋ ๋๋ง ์ฑ๋ฅ ์ฑ๋ฅ ์ต์ ํ ์ ๋ต์ ์ดํดํ๊ณ ์๋์ง ํ์ธํฉ๋๋ค.
๐ฃ ์์ฒ ์ด์ Naive ๊ตฌํ (Bad Case)
์์ฒ ์ด๋ ๋ชจ๋ ๋ฐ์ดํฐ๋ฅผ ํ๋์ ๊ฑฐ๋ํ Context์ ๋ชฐ์๋ฃ์์ต๋๋ค.
// ๐ฃ ์์ฒ : "Context ํ๋๋ง ์์ผ๋ฉด ์ด๋์๋ ๊บผ๋ด ์ธ ์ ์์ผ๋ ํธํด์!"
const AppContext = createContext();
function AppProvider({ children }) {
const [user, setUser] = useState(null);
const [theme, setTheme] = useState('light');
const [posts, setPosts] = useState([]); // โ ๏ธ ์ฐ๊ด ์๋ ๋ฐ์ดํฐ๋ค์ด ํ๋์ ๋ฌถ์
return (
<AppContext.Provider value={{ user, theme, posts }}>
{children}
</AppContext.Provider>
);
}
// โ ๏ธ ๋ฒ๊ทธ: user ์ ๋ณด๋ง ๋ฐ๋์ด๋ posts๋ฅผ ์ฌ์ฉํ๋ ์ปดํฌ๋ํธ๊น์ง ๋ชจ๋ ๋ฆฌ๋ ๋๋ง๋จ๐ฆ ์ํธ์ ํฉํญ ์กฐ์ธ
"์์ฒ ๋, Context๋ ๊ฐ์ ๋ฐฐ๋ฌํด ์ฃผ๋ 'ํ๋ฐฐ ๊ธฐ์ฌ'์ผ ๋ฟ์ด์์. ์์๊ฐ ํ๋๋ฉด, ์์ ์๋ ๋ฌผ๊ฑด ์ค ํ๋๋ง ๋ฐ๋์ด๋ ์์ ์ ์ฒด๋ฅผ ๋ค์ ๋ฐฐ๋ฌํด์ผ ํ์ฃ . ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ค์ ์ด '์์'๋ฅผ ์๊ฒ ์ชผ๊ฐ๊ฑฐ๋, ํ์ํ ๋ฌผ๊ฑด๋ง ์ ๊ณจ๋ผ๋ด๋ ๊ธฐ๋ฅ์ ์ ๊ณตํฉ๋๋ค."
๐ฆ ์ํธ์ ์ํคํ ์ฒ ๊ฐ์ด๋ (Good Case)
์ํธ ๋ฆฌ๋๊ฐ Zustand๋ฅผ ํ์ฉํด ๊ด์ฌ์ฌ๋ณ๋ก ์คํ ์ด๋ฅผ ๋ถ๋ฆฌํ๊ณ ์ต์ ํํ๋ ๋ฒ์ ๋ณด์ฌ์ค๋๋ค.
// ๐ฆ ์ํธ: "๊ด์ฌ์ฌ๋ฅผ ๋ถ๋ฆฌํ๊ณ , ํ์ํ ์ํ๋ง ๊ตฌ๋
(Subscribe)ํ์ธ์."
// Zustand: Flux ํจํด ๊ธฐ๋ฐ์ ๊ฐ๋ฒผ์ด ์คํ ์ด
const useThemeStore = create((set) => ({
theme: 'light',
toggleTheme: () => set((state) => ({ theme: state.theme === 'light' ? 'dark' : 'light' })),
}));
function ThemeButton() {
// โ
Selector๋ฅผ ์ฌ์ฉํ์ฌ theme๋ง ๊ตฌ๋
. ๋ค๋ฅธ ์ํ๊ฐ ๋ฐ๋์ด๋ ์ฌ๊ธฐ๋ ์์ ํจ!
const theme = useThemeStore((state) => state.theme);
const toggleTheme = useThemeStore((state) => state.toggleTheme);
return <button onClick={toggleTheme}>{theme} ๋ชจ๋</button>;
}๐ ๋ ๋ฒจ๋ณ ๋ต๋ณ ๊ฐ์ด๋ (Self-Check)
- Level 1 (Junior): "Context API๋ ๋ฆฌ์กํธ ๋ด์ฅ ๊ธฐ๋ฅ์ด๊ณ , ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ ์ถ๊ฐ ์ค์น๊ฐ ํ์ํฉ๋๋ค. Context๋ ๋ฐ์ดํฐ๊ฐ ๋ง์์ง๋ฉด ์ฑ๋ฅ์ด ๋จ์ด์ง ์ ์์ต๋๋ค."
- Level 2 (Senior): "Context API๋ '์ํ ์ ํ'๋ฅผ ๋ด๋นํ๋ฉฐ, ํ์ ์ปดํฌ๋ํธ์ ๋ฆฌ๋ ๋๋ง์ ๋ฐฉ์งํ๋ ค๋ฉด
useMemo๋ Context ์ชผ๊ฐ๊ธฐ(Splitting)๊ฐ ํ์ํจ์ ์ค๋ช ํฉ๋๋ค. ์ธ๋ถ ์ํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ '๋ฐํ-๊ตฌ๋ (Pub-Sub)' ๋ชจ๋ธ์ ํตํด ๋ฆฌ์กํธ ๋ฐ์์ ์ํ๋ฅผ ๊ด๋ฆฌํ๋ฉฐ ์ต์ ํ๋ ๋ฆฌ๋ ๋๋ง์ ์ ๊ณตํจ์ ์ธ๊ธํฉ๋๋ค." - Level 3 (Specialist): "๋์์ฑ ๋ชจ๋(Concurrent Mode)์์์ 'Tearing' ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ค์ด
useSyncExternalStore๋ฅผ ์ด๋ป๊ฒ ํ์ฉํ๋์ง ์ค๋ช ํฉ๋๋ค. ๋ํ Zustand์ ๊ฐ๋ฒผ์ด ๋ฒ๋ค ์ฌ์ด์ฆ์ Jotai์ Bottom-up ๋ฐฉ์์ด ์ค์ ๋๊ท๋ชจ ํ๋ก์ ํธ ์ํคํ ์ฒ์์ ์ด๋ค ํธ๋ ์ด๋์คํ๋ฅผ ๊ฐ๋์ง ๋ถ์ํฉ๋๋ค."
Q2. Flux ์ํคํ ์ฒ์ ํต์ฌ ์๋ฆฌ์, ์ ๋ฆฌ์กํธ ์ํ๊ณ์์ ์ด ํจํด์ด ์ฃผ๋ฅ๊ฐ ๋์๋์ง ์ค๋ช ํด ๋ณด์ธ์.
๐ฏ ์ถ์ ์๋
๋ฐ์ดํฐ ํ๋ฆ์ ์์ธก ๊ฐ๋ฅ์ฑ(Predictability)์ด ๋๊ท๋ชจ ์ฑ์์ ์ ์ค์ํ์ง, ๊ทธ๋ฆฌ๊ณ ๋ณต์กํ ์ํ ์ ๋ฐ์ดํธ๋ฅผ ์ถ์ ํ๊ธฐ ์ํ ์ค๊ณ ๋ฅ๋ ฅ์ ํ์ธํฉ๋๋ค.
๐ฃ ์์ฒ ์ด์ Naive ๊ตฌํ (Bad Case)
์์ฒ ์ด๋ ์ฌ๋ฌ ์ปดํฌ๋ํธ์์ ์๋ก์ ์ํ๋ฅผ ์ง์ ์์ ํ๋ '์๋ฐฉํฅ ๋ฐ์ธ๋ฉ' ์ง์ฅ์ ๋น ์ก์ต๋๋ค.
// ๐ฃ ์์ฒ : "A ์ปดํฌ๋ํธ์์ B ์ปดํฌ๋ํธ ํจ์๋ฅผ ์ง์ ํธ์ถํด์ ์ํ๋ฅผ ๋ฐ๊ฟ๊ฒ์!"
function ComponentA({ updateB }) {
return <button onClick={() => updateB('์๋ก์ด ๊ฐ')}>B ๋ฐ๊พธ๊ธฐ</button>;
}
// โ ๏ธ ๊ฒฐ๊ณผ: ๋ฐ์ดํฐ๊ฐ ์ด๋์ ์ ๋ฐ๋์๋์ง ์ถ์ ํ๊ธฐ๊ฐ ๋ถ๊ฐ๋ฅํด์ง (๋๋ฒ๊น
์ง์ฅ)๐ฆ ์ํธ์ ํฉํญ ์กฐ์ธ
"์์ฒ ๋, ๋ฐ์ดํฐ๊ฐ ์ด๋ฆฌ์ ๋ฆฌ ํ์ด ๋ค๋๋ฉด ์ฑ์ด ์ปค์ก์ ๋ ๋ฒ์ธ์ ์ฐพ์ ์ ์์ด์.Flux๋ '๋ฐ์ดํฐ๋ ๋ฌด์กฐ๊ฑด ํ ๊ธธ๋ก๋ง ๊ฐ๋ค'๋ ๊ท์น์ ์ธ์ ๋ฒ์ฃ(?)๋ฅผ ์๋ฐฉํฉ๋๋ค."
๐ฆ ์ํธ์ ์ํคํ ์ฒ ๊ฐ์ด๋ (Good Case)
์ํธ ๋ฆฌ๋๊ฐ ๋จ๋ฐฉํฅ ๋ฐ์ดํฐ ํ๋ฆ์ ์ ์์ ์ค๋ช ํฉ๋๋ค.
// ๐ฆ ์ํธ: "๋ชจ๋ ๋ณํ๋ 'Action'์ด๋ผ๋ ๊ธฐ๋ก์ ๋จ๊ฒจ์ผ ํฉ๋๋ค."
// 1. Action: ์ด๋ค ๋ณํ๊ฐ ์ผ์ด๋ ์ง ์ ์ (์: { type: 'ADD_POST' })
// 2. Dispatcher/Reducer: Action์ ๋ณด๊ณ ์ด๋ป๊ฒ ์ํ๋ฅผ ๋ฐ๊ฟ์ง ๊ฒฐ์
// 3. Store: ์ ์ผํ ์ง์ค์ ์์ฒ (Single Source of Truth)
// 4. View: Store์ ๋ณํ๋ฅผ ๊ฐ์งํ์ฌ ํ๋ฉด ๊ฐฑ์
// Zustand/Redux ํจํด
const usePostStore = create((set) => ({
posts: [],
// ๋ณํ์ '์ด์ '๋ฅผ ๋ช
ํํ ํ๋ ์ก์
ํจ์
addPost: (newPost) => set((state) => ({ posts: [...state.posts, newPost] })),
}));๐ ๋ ๋ฒจ๋ณ ๋ต๋ณ ๊ฐ์ด๋ (Self-Check)
- Level 1 (Junior): "Flux๋ ๋ฐ์ดํฐ๊ฐ ํ ๋ฐฉํฅ์ผ๋ก ํ๋ฅด๊ฒ ํ๋ ํจํด์ ๋๋ค. ์์ธกํ๊ธฐ ์ฝ๋ค๋ ์ฅ์ ์ด ์์ต๋๋ค."
- Level 2 (Senior): "MVC ํจํด์ ๋ณต์ก์ฑ์ ํด๊ฒฐํ๊ธฐ ์ํด ๋ฑ์ฅํ์์ ์ค๋ช ํฉ๋๋ค. ์ํ ์ ๋ฐ์ดํธ ๋ก์ง์ด View์ ๋ถ๋ฆฌ๋์ด ์์ด ํ ์คํธ๊ฐ ์ฝ๊ณ , ๋ชจ๋ ์ํ ๋ณํ๊ฐ ์์ ํจ์(Reducer)์ ์ก์ ๊ฐ์ฒด๋ฅผ ํตํด ์ผ์ด๋๋ฏ๋ก ๋๋ฒ๊น ์ด ์ฉ์ดํจ์ ๊ฐ์กฐํฉ๋๋ค."
- Level 3 (Specialist): "Flux ํจํด์ ๋จ์ ์ธ '๋ณด์ผ๋ฌํ๋ ์ดํธ' ๋ฌธ์ ๋ฅผ Zustand๊ฐ ์ด๋ป๊ฒ ํด๊ฒฐํ๋์ง(Redux ๋๋น ๋จ์ํ) ๋ถ์ํฉ๋๋ค. ๋ํ ๋ฏธ๋ค์จ์ด(Middleware)๋ฅผ ํตํด ๋ก๊น , ์์์ฑ ์ ์ฅ(Persistence), ๋น๋๊ธฐ ์ฒ๋ฆฌ ๋ฑ์ ํ์ดํ๋ผ์ธ ํํ๋ก ํ์ฅํ๋ ๊ณ ๊ธ ์ํคํ ์ฒ ์ค๊ณ ๊ฒฝํ์ ์ ์ํฉ๋๋ค."
๐ ์ค์ ๋ณํ ์ง๋ฌธ (Related Variations)
Q45. Props Drilling์ ํด๊ฒฐํ๊ธฐ ์ํ ๋จ๊ณ๋ณ ์ ๋ต์ ๋ฌด์์ธ๊ฐ์?
- ๐ฏ ์ถ์ ์๋: ๋ฌด์กฐ๊ฑด ์ ์ญ ์ํ๋ฅผ ์ฐ๊ธฐ๋ณด๋ค, ๋ฆฌ์กํธ ๋ต๊ฒ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ ํฉ๋ฆฌ์ ์ธ ํ๋จ ๋ฅ๋ ฅ์ ํ์ธํฉ๋๋ค.
- ๐ก ํต์ฌ ์๋ฆฌ & ๋ต๋ณ: ์ฒซ ๋ฒ์งธ๋ **์ปดํฌ๋ํธ ํฉ์ฑ(Component Composition)**์
๋๋ค. Props๋ฅผ ๋ฐ๋ ์์ ๋์ , ์์์
children์ผ๋ก ๋๊ฒจ ์ค๊ฐ ์ปดํฌ๋ํธ๊ฐ ์กด์ฌ๋ฅผ ๋ชจ๋ฅด๊ฒ ๋ง๋ญ๋๋ค. ๋ ๋ฒ์งธ๋ ์ฐ๊ด ์๋ ์ปดํฌ๋ํธ๋ผ๋ฆฌ ๋ฌถ์ด Context๋ฅผ ์์ฑํ๋ ์ง์ญ์ Context ํ์ฉ์ ๋๋ค. ์ ์ญ ์ํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ ์ด ๋ชจ๋ ๋ฐฉ๋ฒ์ผ๋ก๋ ํด๊ฒฐ์ด ์ ๋ ๋งํผ '์ฑ ์ ์ฒด'์์ ๊ณต์ ๊ฐ ํ์ํ ๋ ์ตํ์ ์๋จ์ผ๋ก ์ ํํด์ผ ์ฝ๋์ ๊ฒฐํฉ๋๋ฅผ ๋ฎ์ถ ์ ์์ต๋๋ค.
Q52. Zustand์ Selector๋ฅผ ์ฌ์ฉํ ๋ ๊ฐ์ฒด๋ฅผ ์ง์ ๋ฐํํ๋ฉด ๋ฐ์ํ๋ ๋ฌธ์ ๋ ๋ฌด์์ธ๊ฐ์?
- ๐ฏ ์ถ์ ์๋: ๋ฆฌ๋ ๋๋ง ์กฐ๊ฑด์ธ '์ฐธ์กฐ ๋์ผ์ฑ(Reference Identity)'์ ๊น์ด ์ดํดํ๊ณ ์๋์ง ํ์ธํฉ๋๋ค.
- ๐ก ํต์ฌ ์๋ฆฌ & ๋ต๋ณ:
state => ({ a: state.a, b: state.b })์ฒ๋ผ ๋งค๋ฒ ์๋ก์ด ๊ฐ์ฒด๋ฅผ ๋ง๋ค์ด์ ๋ฐํํ๋ฉด, ์ค์ ๊ฐ์ด ๊ฐ๋๋ผ๋ ์ฐธ์กฐ ์ฃผ์๊ฐ ๊ณ์ ๋ฐ๋์ด ๋งค๋ฒ ๋ฆฌ๋ ๋๋ง์ด ์ผ์ด๋ฉ๋๋ค. ์ด๋ฅผ ๋ฐฉ์งํ๋ ค๋ฉด ๊ฐ๋ณ ๊ฐ์ ์์ ํ์ ์ผ๋ก ๋ฐ๋ก ๊ฐ์ ธ์ค๊ฑฐ๋, Zustand์์ ์ ๊ณตํ๋shallow๋น๊ต ํจ์๋ฅผ ๋ ๋ฒ์งธ ์ธ์๋ก ๋๊ฒจ ๊ฐ์ฒด ๋ด๋ถ์ '๊ฐ'๋ค์ด ๋ณํ์ ๋๋ง ๋ฆฌ๋ ๋๋ง๋๊ฒ ๊ฐ์ ํด์ผ ํฉ๋๋ค.
Q60. ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฐ์ง ์๊ณ ๋ฆฌ์กํธ๋ง์ผ๋ก ์ํ ๊ด๋ฆฌ ์์คํ ์ ๊ตฌ์ถํ๋ค๋ฉด ์ด๋ค ๊ตฌ์กฐ๋ฅผ ์ ์ํ์๊ฒ ์ต๋๊น?
- ๐ฏ ์ถ์ ์๋: ๋๊ตฌ์ ์์กดํ์ง ์๋ ์์ ๋ฆฌ์กํธ ์ค๊ณ ์ญ๋์ ํ์ธํฉ๋๋ค.
- ๐ก ํต์ฌ ์๋ฆฌ & ๋ต๋ณ:
useReducer์useContext๋ฅผ ์กฐํฉํ์ฌ 'Mini Redux' ํํ์ ๊ตฌ์กฐ๋ฅผ ์ ์ํ ์ ์์ต๋๋ค.Action๊ณผReducer๋ก ๋ก์ง์ ์ ํํํ๊ณ , ์ด๋ฅผ Context๋ฅผ ํตํด ํ์๋ก ์ฃผ์ ํ๋ ๋ฐฉ์์ ๋๋ค. ์ด๋ ์ฑ๋ฅ ์ต์ ํ๋ฅผ ์ํด ํ ๋ง ์ ์ฉ Context, ์ ์ ์ ๋ณด ์ ์ฉ Context ๋ฑ์ผ๋ก **Context๋ฅผ ์ธ๋ถํ(Splitting)**ํ๊ณ , ํ์์ ์ปดํฌ๋ํธ๋ฅผReact.memo๋ก ๊ฐ์ธ ๋ถํ์ํ ์ ํ๋ฅผ ๋ง๋ ์ค๊ณ๊ฐ ํต์ฌ์ ๋๋ค.
๐ฃ ์์ฒ ์ด์ ๋ณต๊ธฐ ์ผ๊ธฐ
์ค๋ 'Context๋ ์ํ ๊ด๋ฆฌ๊ฐ ์๋๋ค'๋ผ๋ ์ํธ ๋์ ๋ง์์ ๋จธ๋ฆฌ๋ฅผ ํ ๋ ๋ง์ ๊ธฐ๋ถ์ด๋ค. ๊ทธ๋์ ๋๋ ์์ ์์์ ์ฐ๋ ๊ธฐ(?)๋ฅผ ๊ฐ๋ ๋ด์ ํ์ด์ง ์ ์ฒด์ ๋ฟ๋ฆฌ๊ณ ์์๋ค. Zustand๋ก ์คํ ์ด๋ฅผ ์ชผ๊ฐ๊ณ ๋๋ ์ฝ๋๋ ๊ฐ๊ฒฐํด์ง๊ณ , ๊ฐ๋ฐ์ ๋๊ตฌ์ ๋ฆฌ๋ ๋๋ง ํ์ด๋ผ์ดํธ๊ฐ ์ ์ ํด์ง๋ ๊ฑธ ๋ณด๋ ๋ง์์ด ํ์จํด์ก๋ค.
๐ก "์ํ ๊ด๋ฆฌ๋ ๋จ์ํ ๊ฐ์ ์ ์ฅํ๋ ๊ฒ์ด ์๋๋ผ, ๋ณํ์ ๋ฒ์๋ฅผ ํต์ ํ๋ ์์ ์ด๋ค."
๋ด์ผ์ ํด๋ผ์ด์ธํธ์ ์๋ฒ ์ฌ์ด์ ๊ฐ๊ต, 'Data Fetching๊ณผ ์๋ฒ ์ํ'๋ฅผ ๋ฐฐ์ธ ์ฐจ๋ก๋ค. ๋น๋๊ธฐ ๋ฐ์ดํฐ๋ ๋ ์ด๋ค ๋ณต์กํจ์ผ๋ก ๋๋ฅผ ๊ดด๋กญํ์ง ๊ธฐ๋๋๋ค! ๐ก๐จ