React 16.3 Context API 실무 적용기

배경

프로젝트에서 Redux로 모든 전역 상태를 관리하고 있었는데, 테마 설정이나 다국어 같은 간단한 값들까지 action, reducer를 만드는 게 과했다. React 16.3에서 정식 Context API가 나왔다는 소식을 듣고 일부 상태를 마이그레이션해봤다.

기존 구조의 문제

테마 하나 바꾸려면 아래 파일들을 수정해야 했다.

  • actions/theme.js
  • reducers/theme.js
  • constants/actionTypes.js
  • connect로 연결된 모든 컴포넌트

단순히 'light'와 'dark' 문자열만 전달하면 되는데 보일러플레이트가 너무 많았다.

Context API 적용

// ThemeContext.js
import React from 'react';

const ThemeContext = React.createContext('light');

export class ThemeProvider extends React.Component {
  state = { theme: 'light' };

  toggleTheme = () => {
    this.setState(prev => ({
      theme: prev.theme === 'light' ? 'dark' : 'light'
    }));
  };

  render() {
    return (
      <ThemeContext.Provider
        value={{
          theme: this.state.theme,
          toggleTheme: this.toggleTheme
        }}
      >
        {this.props.children}
      </ThemeContext.Provider>
    );
  }
}

export const ThemeConsumer = ThemeContext.Consumer;

사용하는 쪽도 간결해졌다.

import { ThemeConsumer } from './ThemeContext';

const Header = () => (
  <ThemeConsumer>
    {({ theme, toggleTheme }) => (
      <header className={theme}>
        <button onClick={toggleTheme}>테마 변경</button>
      </header>
    )}
  </ThemeConsumer>
);

결과

  • Redux 코드 200줄 삭제
  • 새 개발자가 이해하기 쉬워짐
  • 번들 사이즈 약간 감소

모든 상태를 Context로 옮길 생각은 없다. Redux DevTools나 미들웨어가 필요한 복잡한 상태는 그대로 두고, 단순 전역 값만 Context로 관리하는 하이브리드 방식이 현실적이다.