코드도보통지

1관문. Context Selector Pattern

관문 1 / 7

Context를 분리하여 count 변경이 theme 소비자를 리렌더하지 않도록 최적화하라.

📖 이론 비급

Context Selector: 구독 범위 최소화

단일 Context에 여러 값을 넣으면, 하나가 바뀔 때 모든 소비자가 리렌더된다. 컨텍스트는 선택적 구독(selector)을 지원하지 않기 때문이다.

해결책: 도메인별로 Context를 분리하라. ThemeContext, CountContext를 각각 만들면 각 소비자는 필요한 컨텍스트만 구독하여 불필요한 리렌더를 피한다.

⚔️ 수련 코드

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

// 문제: 하나의 Context에 모든 값을 담으면 모두가 리렌더된다
const AppContext = createContext();

// TODO: ThemeContext와 CountContext로 분리하라

function ThemeToggle() {
  const { theme, setTheme } = useContext(AppContext);
  console.log('ThemeToggle 렌더');
  return <button onClick={() => setTheme(t => t === 'light' ? 'dark' : 'light')}>테마: {theme}</button>;
}

function Counter() {
  const { count, setCount } = useContext(AppContext);
  console.log('Counter 렌더');
  return <button onClick={() => setCount(c => c + 1)}>카운트: {count}</button>;
}

export default function App() {
  const [theme, setTheme] = useState('light');
  const [count, setCount] = useState(0);

  return (
    <AppContext.Provider value={{ theme, setTheme, count, setCount }}>
      <ThemeToggle />
      <Counter />
    </AppContext.Provider>
  );
}