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개발자의 의견을 모두 반영했지만, 관리자로서 유지보수성에 여전히 의구심이 있었기 때문에 주의를 당부했던 기억이 난다.

 

Posted by JMAN