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로 관리하는 하이브리드 방식이 현실적이다.