React 16.3 새 Context API 도입기

배경

회사 프로젝트에서 사용자 인증 정보와 테마 설정을 전역으로 관리하기 위해 구 Context API를 사용하고 있었다. React 16.3이 릴리즈되면서 새로운 Context API가 정식으로 공개되어 마이그레이션을 진행했다.

기존 방식의 문제

구 Context API는 getChildContextchildContextTypes를 사용했는데, PropTypes 의존성과 암묵적인 전달 방식이 불편했다.

class ThemeProvider extends React.Component {
  getChildContext() {
    return { theme: this.props.theme };
  }
  render() {
    return this.props.children;
  }
}
ThemeProvider.childContextTypes = {
  theme: PropTypes.object
};

새 Context API 적용

React.createContext()를 사용하면 훨씬 명시적이다.

const ThemeContext = React.createContext({ theme: 'light' });

class ThemeProvider extends React.Component {
  render() {
    return (
      <ThemeContext.Provider value={this.props.theme}>
        {this.props.children}
      </ThemeContext.Provider>
    );
  }
}

// 소비하는 쪽
class Button extends React.Component {
  render() {
    return (
      <ThemeContext.Consumer>
        {theme => <button className={theme.mode}>{this.props.children}</button>}
      </ThemeContext.Consumer>
    );
  }
}

결과

PropTypes 없이도 컨텍스트를 사용할 수 있고, Consumer 패턴으로 어디서 컨텍스트를 사용하는지 명확해졌다. 인증 상태 관리 코드도 동일하게 리팩토링했다. TypeScript 도입을 고려 중인데, 새 API가 타입 정의하기 더 수월할 것 같다.

다만 아직 HOC 패턴에 익숙한 팀원들이 많아서 점진적으로 적용 중이다.