React Hook – UseContext 이해하기


React는 컴포넌트 간 상태를 관리하고 데이터를 공유하기 위한 다양한 도구를 제공합니다. 그중에서도 Context APIuseContext 훅은 컴포넌트 트리의 여러 레벨에서 데이터를 쉽게 공유할 수 있도록 도와주는 강력한 기능입니다. 이 포스트에서는 Context APIuseContext의 특징, 사용 시 주의할 점, 언제 사용하는 것이 좋은지, 그리고 예제를 통해 이를 어떻게 활용할 수 있는지 알아보겠습니다.


1. Context API란?

Context API는 React에서 전역 상태를 관리하고 컴포넌트 간 데이터를 공유하기 위한 기능입니다. 이를 통해 “prop drilling” 문제를 해결할 수 있습니다. Prop drilling이란 데이터를 필요로 하지 않는 중간 컴포넌트에도 props를 전달해야 하는 상황을 말합니다.

Context API의 주요 특징:

  1. 전역 상태 관리: Context를 사용하면 데이터를 전역적으로 관리하고 필요한 컴포넌트에서 바로 접근할 수 있습니다.
  2. 효율적인 데이터 공유: 컴포넌트 트리의 어느 레벨에서도 데이터를 쉽게 공유할 수 있습니다.
  3. Prop Drilling 방지: 중간 컴포넌트를 거치지 않고 필요한 컴포넌트에서 데이터를 직접 사용할 수 있습니다.

2. useContext란?

useContext는 React의 훅 중 하나로, 함수형 컴포넌트에서 Context 데이터를 쉽게 사용할 수 있도록 도와줍니다. 이를 통해 Consumer 컴포넌트를 사용하지 않고도 Context 데이터를 가져올 수 있습니다.

useContext의 주요 특징:

  1. Context에 직접 접근: useContext를 사용하면 Context 데이터를 간단하게 가져올 수 있습니다.
  2. 코드 가독성 향상: Consumer 컴포넌트를 사용하는 것보다 코드가 간결하고 읽기 쉬워집니다.
  3. 함수형 컴포넌트와 호환: React의 최신 함수형 컴포넌트와 함께 사용하기에 적합합니다.

3. Context API와 useContext를 언제 사용해야 할까?

React의 Context API와 useContext Hook은 컴포넌트 트리에서 전역 상태를 관리하거나, 공유 데이터를 효율적으로 전달하기 위해 사용되는 강력한 도구이지만, 모든 상황에서 적합한 것은 아닙니다. 다음과 같은 경우에 사용하는 것이 좋습니다:

  1. 전역 상태 공유: 테마, 인증 상태, 사용자 설정 등 여러 컴포넌트에서 공통적으로 사용하는 데이터를 관리할 때.
  2. Prop Drilling 방지: 데이터를 여러 컴포넌트에 전달해야 하지만, 중간 컴포넌트가 데이터를 직접 사용하지 않는 경우.
  3. 가벼운 상태 관리: 작은 규모의 애플리케이션에서 Redux와 같은 복잡한 상태 관리 라이브러리 대신 사용할 때.

3.1. 전역적으로 데이터를 공유해야 할 때

  • 여러 컴포넌트에서 동일한 데이터를 필요로 하는 경우, Context API를 사용하면 데이터를 쉽게 공유할 수 있습니다.
  • 예: 사용자 인증 정보, 테마 설정, 언어 설정 등.

예시: 사용자 인증 정보 공유

const UserContext = React.createContext();

function App() {
  const user = { name: "John", loggedIn: true };

  return (
    <UserContext.Provider value={user}>
      <Navbar />
      <Dashboard />
    </UserContext.Provider>
  );
}

function Navbar() {
  const user = React.useContext(UserContext);
  return <p>Welcome, {user.name}!</p>;
}

3.2. Props Drilling을 피하고 싶을 때

  • 데이터나 함수를 여러 단계의 자식 컴포넌트로 전달해야 할 때, Context API를 사용하면 중간 컴포넌트에서 불필요하게 props를 전달하지 않아도 됩니다.
  • 예: 깊은 컴포넌트 트리에서 테마나 설정 값을 전달해야 하는 경우.

예시: 테마 설정 전달

const ThemeContext = React.createContext();

function App() {
  return (
    <ThemeContext.Provider value="dark">
      <Toolbar />
    </ThemeContext.Provider>
  );
}

function Toolbar() {
  return (
    <div>
      <ThemedButton />
    </div>
  );
}

function ThemedButton() {
  const theme = React.useContext(ThemeContext);
  return <button className={theme}>Click me</button>;
}

3.3. 라이브러리를 사용하기엔 과도한 경우

  • Redux, MobX와 같은 상태 관리 라이브러리는 강력하지만, 작은 프로젝트나 간단한 상태 공유에는 과도할 수 있습니다.
  • Context API는 React에 내장되어 있어 추가적인 라이브러리 없이 간단한 전역 상태 관리를 구현할 수 있습니다.

예시: 간단한 전역 상태 관리

const CounterContext = React.createContext();

function App() {
  const [count, setCount] = React.useState(0);

  return (
    <CounterContext.Provider value={{ count, setCount }}>
      <Counter />
    </CounterContext.Provider>
  );
}

function Counter() {
  const { count, setCount } = React.useContext(CounterContext);
  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={() => setCount(count + 1)}>Increment</button>
    </div>
  );
}

3.4. 컴포넌트 간의 데이터 의존성이 높을 때

  • 여러 컴포넌트가 동일한 데이터를 참조하거나, 데이터 변경에 따라 동작이 달라지는 경우 Context API를 사용하면 데이터 의존성을 쉽게 관리할 수 있습니다.
  • 예: 다국어 지원(언어 설정), 사용자 권한 관리 등.

4. 언제 사용하지 말아야 할까?

  1. 데이터가 특정 컴포넌트에서만 사용될 때
    • Context API는 전역적으로 데이터를 공유하기 위한 도구입니다. 특정 컴포넌트에서만 필요한 데이터라면, props를 사용하는 것이 더 적합합니다.
  2. 빈번한 상태 업데이트가 필요한 경우
    • Context API는 전역 상태를 관리할 수 있지만, 상태가 자주 변경되면 Context를 구독하는 모든 컴포넌트가 리렌더링됩니다.
    • 이 경우, Redux, Zustand, Recoil과 같은 상태 관리 라이브러리를 사용하는 것이 더 효율적일 수 있습니다.
  3. 복잡한 상태 관리가 필요한 경우
    • Context API는 간단한 전역 상태 관리에 적합합니다. 상태가 복잡하거나 여러 액션과 비동기 작업이 필요한 경우, Redux와 같은 라이브러리를 사용하는 것이 더 적합합니다.

마무리

Context APIuseContext 훅은 React 애플리케이션에서 전역 상태를 관리하고 데이터를 공유하는 데 매우 유용한 도구입니다. Prop Drilling 문제를 해결하고 코드의 가독성을 높이는 데 큰 도움을 줍니다. 하지만 성능 문제와 컴포넌트 재사용성 감소를 방지하기 위해 신중하게 사용해야 합니다.

jeewoo jung 아바타