React 16.3 Context API로 Prop Drilling 해결하기
문제 상황
관리자 페이지 작업 중 사용자 권한 정보를 최상위에서 받아 여러 깊이의 자식 컴포넌트까지 전달해야 했다. 중간 컴포넌트들은 해당 prop을 사용하지 않지만 단순히 전달만 하는 구조였다.
<Layout user={user}>
<Sidebar user={user}>
<Menu user={user}>
<MenuItem user={user} />
</Menu>
</Sidebar>
</Layout>
컴포넌트가 추가될 때마다 prop을 일일이 넘겨야 해서 유지보수가 어려웠다.
Context API 적용
React 16.3에서 정식으로 개선된 Context API를 사용하기로 했다. 기존 legacy context는 불안정하다는 의견이 많아 미뤄왔는데, 이번 버전에서 안정화되었다.
// UserContext.js
import React from 'react';
const UserContext = React.createContext(null);
export default UserContext;
// App.js
import UserContext from './UserContext';
class App extends React.Component {
render() {
return (
<UserContext.Provider value={this.props.user}>
<Layout>
<Sidebar>
<Menu />
</Sidebar>
</Layout>
</UserContext.Provider>
);
}
}
// MenuItem.js
import UserContext from './UserContext';
class MenuItem extends React.Component {
render() {
return (
<UserContext.Consumer>
{user => (
<div>
{user.role === 'admin' && <AdminMenu />}
</div>
)}
</UserContext.Consumer>
);
}
}
결과
중간 컴포넌트들의 prop 전달 코드가 모두 제거되었다. 새로운 컴포넌트를 추가할 때도 Context Consumer만 사용하면 되어 작업 속도가 빨라졌다.
다만 Context를 남용하면 컴포넌트 재사용성이 떨어질 수 있어, 정말 여러 단계를 거쳐 전달해야 하는 데이터에만 사용하기로 했다. 테마, 로케일, 인증 정보 정도가 적합해 보인다.