06. ๐Ÿง  ์ƒํƒœ ๊ด€๋ฆฌ ๋„๊ตฌ์˜ ์ฒ ํ•™๊ณผ ์ตœ์ ํ™” ์ „๋žต

2026๋…„ 4์›” 30์ผ ์ˆ˜์ •๋จ

๐Ÿ“‹ ๊ฐœ์š”

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๋กœ ์ฒ˜๋ฆฌํ•ด์•ผ ํ• ์ง€ ๋ชจ๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค."
  • ๐Ÿฆ ์˜ํ˜ธ (๋ฆฌ๋“œ): "์˜์ฒ  ๋‹˜, Context๋Š” ๊ฐ’์„ ๊นŠ์€ ํŠธ๋ฆฌ๋กœ ์ „๋‹ฌํ•˜๋Š” ๋ฐ ๊ฐ•ํ•˜์ง€๋งŒ, ์ž์ฃผ ๋ฐ”๋€Œ๋Š” ๊ฐ’์˜ ์„ธ๋ฐ€ํ•œ ๊ตฌ๋…๊นŒ์ง€ ์ž๋™์œผ๋กœ ํ•ด๊ฒฐํ•ด ์ฃผ์ง€๋Š” ์•Š์Šต๋‹ˆ๋‹ค. ๋„๊ตฌ์˜ ์ด๋ฆ„๋ณด๋‹ค ๊ทธ ๋„๊ตฌ๊ฐ€ ํ•ด๊ฒฐํ•˜๋ ค๋Š” '๋ณ€ํ™” ๋ฒ”์œ„'๋ฅผ ๋จผ์ € ๋ณด์„ธ์š”."

๋ฉด์ ‘ ์งˆ๋ฌธ 1. 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>;
}

Context๋„ ์ž‘์€ Provider๋กœ ๋‚˜๋ˆ„๊ณ  value๋ฅผ ์•ˆ์ •ํ™”ํ•˜๋ฉด ์ถฉ๋ถ„ํžˆ ์ข‹์€ ์„ ํƒ์ด ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ „์—ญ ์ƒํƒœ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋Š” "Context๊ฐ€ ๋‚˜์˜๋‹ค"๊ฐ€ ์•„๋‹ˆ๋ผ ๋ณ€๊ฒฝ ๋นˆ๋„์™€ ๊ตฌ๋… ๋‹จ์œ„๊ฐ€ ๋” ์„ธ๋ฐ€ํ•œ ๋„๊ตฌ๋ฅผ ์š”๊ตฌํ•  ๋•Œ ๋„์ž…ํ•ฉ๋‹ˆ๋‹ค.

๐Ÿ“Š ๋ ˆ๋ฒจ๋ณ„ ๋‹ต๋ณ€ ๊ฐ€์ด๋“œ (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 ๋ฐฉ์‹์ด ์‹ค์ œ ๋Œ€๊ทœ๋ชจ ํ”„๋กœ์ ํŠธ ์•„ํ‚คํ…์ฒ˜์—์„œ ์–ด๋–ค ํŠธ๋ ˆ์ด๋“œ์˜คํ”„๋ฅผ ๊ฐ–๋Š”์ง€ ๋ถ„์„ํ•ฉ๋‹ˆ๋‹ค."

๋ฉด์ ‘ ์งˆ๋ฌธ 2. 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), ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ ๋“ฑ์„ ํŒŒ์ดํ”„๋ผ์ธ ํ˜•ํƒœ๋กœ ํ™•์žฅํ•˜๋Š” ๊ณ ๊ธ‰ ์•„ํ‚คํ…์ฒ˜ ์„ค๊ณ„ ๊ฒฝํ—˜์„ ์ œ์‹œํ•ฉ๋‹ˆ๋‹ค."

๋ฉด์ ‘ ์งˆ๋ฌธ 45. Props Drilling์„ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•œ ๋‹จ๊ณ„๋ณ„ ์ „๋žต์€ ๋ฌด์—‡์ธ๊ฐ€์š”?

  • ๐ŸŽฏ ์ถœ์ œ ์˜๋„: ๋ฐ”๋กœ ์ „์—ญ ์ƒํƒœ๋ฅผ ์“ฐ๊ธฐ๋ณด๋‹ค, ๋ฆฌ์•กํŠธ๋‹ต๊ฒŒ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋Š” ํ•ฉ๋ฆฌ์ ์ธ ํŒ๋‹จ ๋Šฅ๋ ฅ์„ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.
  • ๐Ÿ’ก ํ•ต์‹ฌ ์›๋ฆฌ & ๋‹ต๋ณ€: ์ฒซ ๋ฒˆ์งธ๋Š” **์ปดํฌ๋„ŒํŠธ ํ•ฉ์„ฑ(Component Composition)**์ž…๋‹ˆ๋‹ค. Props๋ฅผ ๋ฐ›๋Š” ์ž์‹ ๋Œ€์‹ , ์ž์‹์„ children์œผ๋กœ ๋„˜๊ฒจ ์ค‘๊ฐ„ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์กด์žฌ๋ฅผ ๋ชจ๋ฅด๊ฒŒ ๋งŒ๋“ญ๋‹ˆ๋‹ค. ๋‘ ๋ฒˆ์งธ๋Š” ์—ฐ๊ด€ ์žˆ๋Š” ์ปดํฌ๋„ŒํŠธ๋ผ๋ฆฌ ๋ฌถ์–ด Context๋ฅผ ์ƒ์„ฑํ•˜๋Š” ์ง€์—ญ์  Context ํ™œ์šฉ์ž…๋‹ˆ๋‹ค. ์ „์—ญ ์ƒํƒœ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋Š” ์ด ๋ชจ๋“  ๋ฐฉ๋ฒ•์œผ๋กœ๋„ ํ•ด๊ฒฐ์ด ์•ˆ ๋  ๋งŒํผ '์•ฑ ์ „์ฒด'์—์„œ ๊ณต์œ ๊ฐ€ ํ•„์š”ํ•  ๋•Œ ์ตœํ›„์˜ ์ˆ˜๋‹จ์œผ๋กœ ์„ ํƒํ•ด์•ผ ์ฝ”๋“œ์˜ ๊ฒฐํ•ฉ๋„๋ฅผ ๋‚ฎ์ถœ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋ฉด์ ‘ ์งˆ๋ฌธ 52. Zustand์˜ Selector๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ ๊ฐ์ฒด๋ฅผ ์ง์ ‘ ๋ฐ˜ํ™˜ํ•˜๋ฉด ๋ฐœ์ƒํ•˜๋Š” ๋ฌธ์ œ๋Š” ๋ฌด์—‡์ธ๊ฐ€์š”?

  • ๐ŸŽฏ ์ถœ์ œ ์˜๋„: ๋ฆฌ๋ Œ๋”๋ง ์กฐ๊ฑด์ธ '์ฐธ์กฐ ๋™์ผ์„ฑ(Reference Identity)'์„ ๊นŠ์ด ์ดํ•ดํ•˜๊ณ  ์žˆ๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.
  • ๐Ÿ’ก ํ•ต์‹ฌ ์›๋ฆฌ & ๋‹ต๋ณ€: state => ({ a: state.a, b: state.b })์ฒ˜๋Ÿผ ๋งค๋ฒˆ ์ƒˆ๋กœ์šด ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค์–ด์„œ ๋ฐ˜ํ™˜ํ•˜๋ฉด, ์‹ค์ œ ๊ฐ’์ด ๊ฐ™๋”๋ผ๋„ ์ฐธ์กฐ ์ฃผ์†Œ๊ฐ€ ๊ณ„์† ๋ฐ”๋€Œ์–ด ๋งค๋ฒˆ ๋ฆฌ๋ Œ๋”๋ง์ด ์ผ์–ด๋‚  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ ๋ฐฉ์ง€ํ•˜๋ ค๋ฉด ๊ฐœ๋ณ„ ๊ฐ’์„ ์›์‹œ ํƒ€์ž…์œผ๋กœ ๋”ฐ๋กœ ๊ฐ€์ ธ์˜ค๊ฑฐ๋‚˜, Zustand์˜ shallow ๋น„๊ต ๋˜๋Š” useShallow ๊ฐ™์€ ์œ ํ‹ธ๋ฆฌํ‹ฐ๋กœ ๊ฐ์ฒด ๋‚ด๋ถ€ ๊ฐ’์ด ๋ฐ”๋€” ๋•Œ๋งŒ ๋ Œ๋”๋ง๋˜๊ฒŒ ์„ค๊ณ„ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๋ฉด์ ‘ ์งˆ๋ฌธ 60. ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์“ฐ์ง€ ์•Š๊ณ  ๋ฆฌ์•กํŠธ๋งŒ์œผ๋กœ ์ƒํƒœ ๊ด€๋ฆฌ ์‹œ์Šคํ…œ์„ ๊ตฌ์ถ•ํ•œ๋‹ค๋ฉด ์–ด๋–ค ๊ตฌ์กฐ๋ฅผ ์ œ์•ˆํ•˜์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ?

  • ๐ŸŽฏ ์ถœ์ œ ์˜๋„: ๋„๊ตฌ์— ์˜์กดํ•˜์ง€ ์•Š๋Š” ์ˆœ์ˆ˜ ๋ฆฌ์•กํŠธ ์„ค๊ณ„ ์—ญ๋Ÿ‰์„ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.
  • ๐Ÿ’ก ํ•ต์‹ฌ ์›๋ฆฌ & ๋‹ต๋ณ€: useReducer์™€ useContext๋ฅผ ์กฐํ•ฉํ•˜์—ฌ 'Mini Redux' ํ˜•ํƒœ์˜ ๊ตฌ์กฐ๋ฅผ ์ œ์•ˆํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. Action๊ณผ Reducer๋กœ ๋กœ์ง์„ ์ •ํ˜•ํ™”ํ•˜๊ณ , ์ด๋ฅผ Context๋ฅผ ํ†ตํ•ด ํ•˜์œ„๋กœ ์ฃผ์ž…ํ•˜๋Š” ๋ฐฉ์‹์ž…๋‹ˆ๋‹ค. ์ด๋•Œ ์„ฑ๋Šฅ ์ตœ์ ํ™”๋ฅผ ์œ„ํ•ด ํ…Œ๋งˆ ์ „์šฉ Context, ์œ ์ € ์ •๋ณด ์ „์šฉ Context ๋“ฑ์œผ๋กœ **Context๋ฅผ ์„ธ๋ถ„ํ™”(Splitting)**ํ•˜๊ณ , ํ•„์š”์‹œ ์ปดํฌ๋„ŒํŠธ๋ฅผ React.memo๋กœ ๊ฐ์‹ธ ๋ถˆํ•„์š”ํ•œ ์ „ํŒŒ๋ฅผ ๋ง‰๋Š” ์„ค๊ณ„๊ฐ€ ํ•ต์‹ฌ์ž…๋‹ˆ๋‹ค.

๐Ÿ“ ๋งˆ๋ฌด๋ฆฌ ํ€ด์ฆˆ

Q1. Context API๋ฅผ ์ƒํƒœ ๊ด€๋ฆฌ ๋„๊ตฌ์ฒ˜๋Ÿผ ๋‚จ์šฉํ•˜๋ฉด ์–ด๋–ค ๋ฌธ์ œ๊ฐ€ ์ƒ๊ธฐ๊ธฐ ์‰ฌ์šด๊ฐ€์š”?

โœ… ์ •๋‹ต: Provider ๊ฐ’์ด ๋ฐ”๋€” ๋•Œ ๋„“์€ ํ•˜์œ„ ํŠธ๋ฆฌ๊ฐ€ ํ•จ๊ป˜ ๋‹ค์‹œ ๋ Œ๋”๋ง๋˜์–ด ๋ณ€ํ™” ๋ฒ”์œ„๋ฅผ ํ†ต์ œํ•˜๊ธฐ ์–ด๋ ค์›Œ์ง„๋‹ค

๐Ÿ’ก ์ƒ์„ธ ํ•ด์„ค:

  • ์›๋ฆฌ ์„ค๋ช…: Context๋Š” ๊ฐ’์„ ๊นŠ๊ฒŒ ์ „๋‹ฌํ•˜๋Š” ๋„๊ตฌ์ด์ง€, ์„ธ๋ฐ€ํ•œ ๊ตฌ๋…๊ณผ ์—…๋ฐ์ดํŠธ ์ตœ์ ํ™”๋ฅผ ์ž๋™์œผ๋กœ ์ œ๊ณตํ•˜๋Š” ์ƒํƒœ ๊ด€๋ฆฌ ์—”์ง„์ด ์•„๋‹™๋‹ˆ๋‹ค.
  • ์˜ค๋‹ต ํ”ผ๋“œ๋ฐฑ: "์ „์—ญ์œผ๋กœ ๊ณต์œ ๋œ๋‹ค"๋Š” ์ด์œ ๋งŒ์œผ๋กœ ๋ชจ๋“  ์ƒํƒœ๋ฅผ Context์— ๋„ฃ์œผ๋ฉด ํŽธํ•ด ๋ณด์ด์ง€๋งŒ, ๋ Œ๋”๋ง ๋น„์šฉ๊ณผ ๊ด€์‹ฌ์‚ฌ ๊ฒฐํ•ฉ์ด ์ปค์ง‘๋‹ˆ๋‹ค.
  • ๐Ÿ“Œ ํ•ต์‹ฌ ๊ธฐ์–ต๋ฒ•: ์ „์—ญ ์ ‘๊ทผ์„ฑ๊ณผ ์ „์—ญ ์—…๋ฐ์ดํŠธ๋Š” ๋‹ค๋ฅธ ๋ฌธ์ œ์ž…๋‹ˆ๋‹ค.

Q2. Redux, Zustand, Jotai ๊ฐ™์€ ๋„๊ตฌ๋ฅผ ์„ ํƒํ•  ๋•Œ ์˜ํ˜ธ๊ฐ€ ๋จผ์ € ๋ณด๋ผ๊ณ  ํ•œ ๊ธฐ์ค€์€ ๋ฌด์—‡์ธ๊ฐ€์š”?

โœ… ์ •๋‹ต: ์ƒํƒœ์˜ ๋ฒ”์œ„, ๋ณ€๊ฒฝ ๋นˆ๋„, ๊ตฌ๋… ๋‹จ์œ„, ํŒ€์˜ ๋””๋ฒ„๊น…/์šด์˜ ์š”๊ตฌ๊ฐ€ ๋„๊ตฌ์˜ ์ฒ ํ•™๊ณผ ๋งž๋Š”์ง€ ํ™•์ธํ•˜๋Š” ๊ฒƒ

๐Ÿ’ก ์ƒ์„ธ ํ•ด์„ค:

  • ์›๋ฆฌ ์„ค๋ช…: ์ƒํƒœ ๊ด€๋ฆฌ ๋„๊ตฌ๋Š” ์ทจํ–ฅ ๋ฌธ์ œ๊ฐ€ ์•„๋‹ˆ๋ผ ๋ณ€ํ™” ํ†ต์ œ ๋ฐฉ์‹์ž…๋‹ˆ๋‹ค. Redux๋Š” ๋ช…์‹œ์  ์ด๋ฒคํŠธ ํ๋ฆ„, Zustand๋Š” ๊ฐ„๊ฒฐํ•œ store, Jotai๋Š” atom ๋‹จ์œ„ ์กฐํ•ฉ์— ๊ฐ•์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค.
  • ์˜ค๋‹ต ํ”ผ๋“œ๋ฐฑ: "์š”์ฆ˜ ๋งŽ์ด ์“ด๋‹ค"๋Š” ๋„์ž… ๊ทผ๊ฑฐ๊ฐ€ ๋  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ์–ด๋–ค ๋ฌธ์ œ๊ฐ€ ์ค„์–ด๋“œ๋Š”์ง€, ์–ด๋–ค ๋น„์šฉ์ด ์ƒ๊ธฐ๋Š”์ง€ ๋งํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
  • ๐Ÿ“Œ ํ•ต์‹ฌ ๊ธฐ์–ต๋ฒ•: ๋„๊ตฌ ์„ ํƒ์€ ์ธ๊ธฐ ํˆฌํ‘œ๊ฐ€ ์•„๋‹ˆ๋ผ ๋ณ€ํ™” ๋ฒ”์œ„ ์„ค๊ณ„์ž…๋‹ˆ๋‹ค.

Q3. ์˜์ฒ ์ด์˜ ํ…Œ์ŠคํŠธ ํƒ€์ž„: ์˜์ˆ˜๋„ค ์•Œ๋ฆผ ์ƒํƒœ๋ฅผ ์ „์—ญ์œผ๋กœ ์˜ฌ๋ฆฌ๊ธฐ ์ „ ํ™•์ธํ•ด์•ผ ํ•  ์งˆ๋ฌธ์€ ๋ฌด์—‡์ธ๊ฐ€์š”?

โœ… ์ •๋‹ต: ์ด ์ƒํƒœ๊ฐ€ ์—ฌ๋Ÿฌ ํ™”๋ฉด์—์„œ ๋™์‹œ์— ํ•„์š”ํ•˜๊ณ , ๋ณ€๊ฒฝ๋  ๋•Œ ์–ด๋–ค ์ปดํฌ๋„ŒํŠธ๋งŒ ๊ตฌ๋…ํ•ด์•ผ ํ•˜๋Š”์ง€ ํ™•์ธํ•œ๋‹ค

๐Ÿ’ก ์ƒ์„ธ ํ•ด์„ค:

  • ์›๋ฆฌ ์„ค๋ช…: ์ „์—ญ ์ƒํƒœ๋Š” ๊ณต์œ ๊ฐ€ ํŽธํ•ด์ง€๋Š” ๋Œ€์‹  ๋ณ€๊ฒฝ ์˜ํ–ฅ๋„ ์ปค์ง‘๋‹ˆ๋‹ค. ๊ตฌ๋… ๋‹จ์œ„๋ฅผ ์ž‘๊ฒŒ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋Š”์ง€, ์„œ๋ฒ„ ์ƒํƒœ์™€ ์„ž์ด์ง€ ์•Š๋Š”์ง€ ๋จผ์ € ๋ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
  • ์˜ค๋‹ต ํ”ผ๋“œ๋ฐฑ: props drilling์ด ํ•œ๋‘ ๋‹จ๊ณ„ ์žˆ๋‹ค๋Š” ์ด์œ ๋งŒ์œผ๋กœ ์ „์—ญ store๋ฅผ ๋งŒ๋“ค๋ฉด ๊ตฌ์กฐ๊ฐ€ ๋” ์ปค์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ๐Ÿ“Œ ํ•ต์‹ฌ ๊ธฐ์–ต๋ฒ•: ์ƒํƒœ๋ฅผ ์˜ฌ๋ฆฌ๊ธฐ ์ „์— ์˜ํ–ฅ ๋ฒ”์œ„๋ฅผ ๊ทธ๋ฆฝ๋‹ˆ๋‹ค.

๐Ÿฃ ์˜์ฒ ์ด์˜ ํ‡ด๊ทผ ์ผ๊ธฐ

์˜ค๋Š˜์€ ์ƒํƒœ ๊ด€๋ฆฌ ๋„๊ตฌ ์ด๋ฆ„์„ ๋งŽ์ด ์•„๋Š” ๊ฒƒ๋ณด๋‹ค, ์ƒํƒœ๊ฐ€ ์™œ ๋ฐ”๋€Œ๊ณ  ์–ด๋””๊นŒ์ง€ ํผ์ ธ์•ผ ํ•˜๋Š”์ง€ ์„ค๋ช…ํ•˜๋Š” ๊ฒŒ ๋” ์ค‘์š”ํ•˜๋‹ค๋Š” ๊ฑธ ๋ฐฐ์› ๋‹ค. ์˜ˆ์ „์˜ ๋‚˜๋Š” Context์— ๋„ฃ์œผ๋ฉด ๊น”๋”ํ•˜๋‹ค๊ณ  ์ƒ๊ฐํ–ˆ๋Š”๋ฐ, ์‚ฌ์‹ค์€ ๋ณ€ํ™” ๋ฒ”์œ„๋ฅผ ํ™”๋ฉด ์ „์ฒด๋กœ ๋„“ํžˆ๊ณ  ์žˆ์—ˆ์„์ง€๋„ ๋ชจ๋ฅธ๋‹ค.

๐Ÿ’ก "์ƒํƒœ ๊ด€๋ฆฌ๋Š” ๊ฐ’์„ ๋ณด๊ด€ํ•˜๋Š” ๊ธฐ์ˆ ์ด ์•„๋‹ˆ๋ผ, ๋ณ€ํ™”๊ฐ€ ํผ์ง€๋Š” ๋ฒ”์œ„๋ฅผ ์„ค๊ณ„ํ•˜๋Š” ์ผ์ด๋‹ค."

๋‹ค์Œ ๋ฆฌ๋ทฐ์—์„œ๋Š” "์ด๊ฑฐ ์ „์—ญ์œผ๋กœ ๋นผ์ฃ "๋ผ๊ณ  ๋งํ•˜๊ธฐ ์ „์—, ์–ด๋–ค ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๊ตฌ๋…ํ•ด์•ผ ํ•˜๊ณ  ์–ด๋–ค ์ปดํฌ๋„ŒํŠธ๋Š” ๋ชฐ๋ผ๋„ ๋˜๋Š”์ง€ ๋จผ์ € ๊ทธ๋ ค๋ด์•ผ๊ฒ ๋‹ค. ์˜์ฒ ์ด ์ด์ œ ๋„๊ตฌ๋ณด๋‹ค ํ๋ฆ„์„ ๋จผ์ € ๋ฌป๋Š” ์ชฝ์œผ๋กœ ์กฐ๊ธˆ ์ž๋ผ๊ณ  ์žˆ๋‹ค.