React 16.3 Context API로 props drilling 해결하기

문제 상황

사용자 인증 정보를 최상위 컴포넌트에서 관리하고 있었는데, 5~6단계 깊이의 자식 컴포넌트까지 props로 계속 전달해야 했다. 중간 컴포넌트들은 해당 데이터를 사용하지도 않으면서 단순히 전달만 하는 역할이었다.

// 기존 방식
<App user={user}>
  <Layout user={user}>
    <Content user={user}>
      <Sidebar user={user}>
        <UserProfile user={user} />

Context API 도입

React 16.3에서 정식으로 추가된 새로운 Context API를 적용했다. 기존 legacy context와 달리 명시적이고 안전한 방식으로 동작한다.

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

const UserContext = React.createContext(null);

export const UserProvider = UserContext.Provider;
export const UserConsumer = UserContext.Consumer;
export default UserContext;

최상위에서 Provider로 감싸고, 필요한 곳에서만 Consumer로 접근하도록 변경했다.

// App.js
<UserProvider value={this.state.user}>
  <Layout>
    <Content>
      <Sidebar>
        <UserProfile />

// UserProfile.js
<UserConsumer>
  {user => (
    <div>{user.name}</div>
  )}
</UserConsumer>

결과

중간 컴포넌트들에서 불필요한 props 전달 코드가 사라졌다. 코드 가독성이 개선되고 컴포넌트 간 결합도도 낮아졌다. 다만 Consumer의 render props 패턴이 다소 장황한 면은 있어서, 작은 규모에서는 오히려 props drilling이 나을 수도 있다는 판단이다.

테마 설정, 다국어 등 전역으로 공유되는 데이터에도 동일한 패턴을 적용할 예정이다.