icon안동민 개발노트

Context API 기초


 React의 Context API는 컴포넌트 트리 전체에 데이터를 효과적으로 전달할 수 있는 방법을 제공합니다.

 이는 props drilling 문제를 해결하고, 전역 상태를 관리하는 데 유용한 도구입니다.

Context API의 개념과 목적

 Context API는 컴포넌트 트리 안에서 전역적으로 데이터를 공유할 수 있게 해주는 React의 내장 기능입니다.

 주요 목적은 다음과 같습니다.

  1. Props drilling 방지
  2. 전역 상태 관리
  3. 테마, 언어 설정 등 애플리케이션 전반에 걸친 데이터 공유

Context 생성 방법

 Context를 생성하는 기본적인 방법은 React.createContext()를 사용하는 것입니다.

ThemeContext.js
import React from 'react';
 
const ThemeContext = React.createContext('light');
 
export default ThemeContext;

 여기서 'light'는 기본값으로, Consumer가 Provider 내부에 없을 때 사용됩니다.

Provider와 Consumer의 역할

 Provider

 Provider는 Context의 값을 하위 컴포넌트에 제공합니다.

import React from 'react';
import ThemeContext from './ThemeContext';
 
function App() {
  return (
    <ThemeContext.Provider value="dark">
      <Toolbar />
    </ThemeContext.Provider>
  );
}

 Consumer

 Consumer는 Context의 값을 사용합니다. 하지만 현대의 React에서는 useContext 훅을 더 많이 사용합니다.

import React from 'react';
import ThemeContext from './ThemeContext';
 
function ThemedButton() {
  return (
    <ThemeContext.Consumer>
      {theme => <button className={theme}>Themed Button</button>}
    </ThemeContext.Consumer>
  );
}

useContext 훅을 이용한 Context 사용법

 useContext 훅은 함수형 컴포넌트에서 Context를 더 쉽게 사용할 수 있게 해줍니다.

import React, { useContext } from 'react';
import ThemeContext from './ThemeContext';
 
function ThemedButton() {
  const theme = useContext(ThemeContext);
  return <button className={theme}>Themed Button</button>;
}

동적 Context 값 사용하기

 실제 애플리케이션에서는 Context 값을 동적으로 변경해야 할 때가 많습니다.

import React, { useState } from 'react';
import ThemeContext from './ThemeContext';
 
function App() {
  const [theme, setTheme] = useState('light');
 
  return (
    <ThemeContext.Provider value={{ theme, setTheme }}>
      <Toolbar />
      <button onClick={() => setTheme(theme === 'light' ? 'dark' : 'light')}>
        Toggle Theme
      </button>
    </ThemeContext.Provider>
  );
}
 
function Toolbar() {
  const { theme, setTheme } = useContext(ThemeContext);
  return (
    <div className={theme}>
      <button onClick={() => setTheme(theme === 'light' ? 'dark' : 'light')}>
        Toggle Theme
      </button>
    </div>
  );
}

Context 사용 시 주의사항

  1. 과도한 사용 주의 : 모든 상태를 Context로 관리하면 컴포넌트 재사용이 어려워질 수 있습니다.
  2. 성능 고려 : Context 값이 변경되면 해당 Context를 사용하는 모든 컴포넌트가 리렌더링됩니다.
  3. 분리된 Context 사용 : 관련 없는 상태들은 별도의 Context로 분리하여 관리하는 것이 좋습니다.

성능 최적화

 Context를 사용할 때 성능을 최적화하기 위한 몇 가지 방법

  1. Context 분할 : 변경 빈도가 다른 값들은 별도의 Context로 분리합니다.
  2. 메모이제이션 : React.memo, useMemo, useCallback을 활용하여 불필요한 리렌더링을 방지합니다.
import React, { useContext, useMemo } from 'react';
import { MyContext } from './MyContext';
 
const MyComponent = React.memo(() => {
  const { value } = useContext(MyContext);
  const expensiveComputation = useMemo(() => {
    // 복잡한 계산 로직
  }, [value]);
 
  return <div>{expensiveComputation}</div>;
});
  1. Context 값 최적화 : 객체 대신 원시 값을 사용하거나, 객체를 사용할 경우 useMemo로 최적화합니다.
const value = useMemo(() => ({ theme, setTheme }), [theme]);
return (
  <ThemeContext.Provider value={value}>
    {children}
  </ThemeContext.Provider>
);

Context API 사용 가이드라인

 Context API는 다음과 같은 상황에서 유용합니다.

  1. 전역 상태 관리 : 사용자 인증 정보, 테마, 언어 설정 등
  2. 깊은 prop drilling 방지 : 여러 레벨의 중첩된 컴포넌트에 데이터를 전달해야 할 때
  3. 컴포넌트 그룹에 대한 공통 데이터 : 특정 컴포넌트 그룹이 공유해야 하는 데이터가 있을 때
  4. 횡단 관심사 처리 : 로깅, 분석 등 여러 컴포넌트에 걸쳐 필요한 기능

 반면, 다음과 같은 경우에는 Context 사용을 재고해 볼 필요가 있습니다.

  1. prop 전달이 한두 단계에 그칠 때 : 이 경우 일반적인 prop 전달이 더 명확할 수 있습니다.
  2. 자주 변경되는 지역 상태 : 이는 해당 컴포넌트나 가까운 상위 컴포넌트에서 관리하는 것이 좋습니다.
  3. 대규모 상태 관리 : 복잡한 상태 로직이 필요한 경우 Redux와 같은 전용 상태 관리 라이브러리를 고려해 볼 수 있습니다.

 정리하자면, Context API는 React 애플리케이션에서 상태 관리를 더 효율적으로 할 수 있게 해주는 강력한 도구입니다.

 props drilling 문제를 해결하고, 컴포넌트 간 데이터 공유를 용이하게 해줍니다.

 그러나 모든 상황에 적합한 해결책은 아니며, 적절한 사용이 중요합니다.

 Context를 효과적으로 사용하려면, 애플리케이션의 구조와 데이터 흐름을 잘 이해하고 있어야 합니다.

 또한, 성능 최적화를 위한 전략을 숙지하고 적용하는 것도 중요합니다.

 Context API를 적절히 활용하면, 더 깔끔하고 유지보수가 쉬운 React 애플리케이션을 개발할 수 있습니다.