Context API는 State(https://swjman.tistory.com/173 에서 다룸)의 글로벌 버전이라고 할 수 있다. 그래서, 우리나라에서는 전역 상태 공유 기능이라고 한다. 교재에서는 사용법을 잘 알려주었다.
하지만, 왜 사용하는지에 대해서는 답이 되지 않아 며칠 동안 리액트의 철학과 나의 경험적 철학을 비교하여 고민을 해보았다. 이 과정에서 GPT가 아주 많은 도움이 되었다.
결론적으로 Context API의 탄생 배경 중 가장 대표적인 건 리액트의 'prop drilling' 이라는 문제적 패턴이 있기 때문이다. 아래의 코드를 보자.
import './styles.css'; function Nested3({ borderStyle }) { return ( <div style={borderStyle}> <h1>Nested3</h1> </div> ); } function Nested2({ borderStyle }) { return ( <div> <h1>Nested2</h1> <Nested3 borderStyle={borderStyle} /> </div> ); } function Nested1({ borderStyle }) { return ( <div> <h1>Nested1</h1> <Nested2 borderStyle={borderStyle} /> </div> ); } function App() { const borderStyle = { border: '10px solid blue' }; return ( <div className="root"> <h1>Prop Drilling</h1> <Nested1 borderStyle={borderStyle} /> </div> ); } export default App;
호출 순서는 App -> Nested1 -> Nested2 -> Nested3 로 4단계를 이루고 있다. borderStyle이란 값을 prop으로 계속 전달하고, 마지막 Nested3 가 해당 값을 사용한다. 즉, Nested3 만 이 값이 필요한데 중간 과정에서 모두 전달 작업을 해주는 것이 바로 'prop drilling' 이다.
이 부분이 바로 내가 오랫동안 고민하게 된 부분이다. 내가 가진 상식으로는 이게 당연하다고 생각을 한다. 하지만, 리액트는 이 부분을 경계하여 다양한 대안을 제시한다.
그 중 하나가 바로 Context API이며 위 코드를 Context API로 리팩토링한 코드는 아래와 같다.
import './styles.css'; import { createContext, useContext } from 'react'; const borderStyle = { border: '10px solid red' }; const borderStyleContext = createContext(borderStyle); function Nested3() { const borderStyle = useContext(borderStyleContext); return ( <div style={borderStyle}> <h1>Nested3</h1> </div> ); } function Nested2() { return ( <div> <h1>Nested2</h1> <Nested3/> </div> ); } function Nested1() { return ( <div> <h1>Nested1</h1> <Nested2/> </div> ); } function App() { const borderStyle = useContext(borderStyleContext); return ( <borderStyleContext.Provider value={{ border: '10px solid blue' }}> <div className="root"> <h1>Context API</h1> <Nested1/> </div> </borderStyleContext.Provider> ); } export default App;
코드는 훨씬 간결하다. 하지만, 구조적으로 보았을 때 Nested3 가 느닷없이 borderStyle을 쓰게 되고, 그 전에 App이 borderStyle 값을 수정하고 있다. 즉, App은 Nested3 가 borderStyle을 쓰게 될 것이라는 걸 알고 있다는 뜻이다. 코딩의 가장 중요한 요소 중 하나인 추상화가 깨지는 것처럼 보인다.
이 부분에 대한 고뇌가 깊어 Context API를 며칠동안 공부해왔던 것이다. 고민 끝에 GPT와 이야기를 나눈 결과는 '당신 말이 맞다' 였다. 즉, 리액트 진영에서는 전역 상태 도구들이 소프트웨어 공학적 철학들을 망가뜨릴 수 있는 점을 인정한단다. 즉, 그걸 알면서도 쓸 수 밖에 없다는 것이다.
물론 철학은 명제가 아니므로 현실을 적극 반영해야 하는 점은 인정한다. 하지만, 철학과 현실에 대한 깊은 고민없이 현실만을 두둔해서는 안된다. 고민 끝에 현실을 반영하는 것과 맹신으로 현실을 추종하는 건 전혀 다른 수준의 결과물을 도출한다.
-----
근래 맡았던 프로젝트에서 FE개발자와 이 부분에 대해 아주 오랜 토론을 했었다. 지금처럼 FE를 구체적으로 공부할 계획은 없었기 때문에 원론적인 이야기를 많이 나눴던 것 같다. 결과적으로는 Zustand 같은 전역 상태 관리자를 적극적으로 이용하는 것으로 결론을 내렸다. FE개발자의 의견을 모두 반영했지만, 관리자로서 유지보수성에 여전히 의구심이 있었기 때문에 주의를 당부했던 기억이 난다.
'Book Study > 생활코딩! React 리액트 프로그래밍' 카테고리의 다른 글
13일차 react-redux - 생활코딩! React 리액트 프로그래밍 (1) | 2025.03.31 |
---|---|
12일차 useReducer - 생활코딩! React 리액트 프로그래밍 (0) | 2025.03.28 |
10일차 스타일드 컴포넌트 - 생활코딩! React 리액트 프로그래밍 (0) | 2025.03.24 |
9일차 React Router DOM(05~06장) - 생활코딩! React 리액트 프로그래밍 (0) | 2025.03.23 |
8일차 React Router DOM(04장) - 생활코딩! React 리액트 프로그래밍 (0) | 2025.03.22 |