“이제 이 배관 공사를 끝낼 시간입니다.”
댄은 Prop Drilling 문제로 고통받던 팀원들 앞에서, 리팩토링 시연을 시작했다. 그의 목표는 중간에 있는 컴포넌트들을 거치지 않고, <App>에서 <UserAvatar>로 데이터를 직접 ‘순간 이동’시키는 것이었다.
그의 첫 번째 단계는, 데이터를 담을 ‘전역 채널’을 만드는 것이었다.
// UserContext.js
import React from 'react';
// 'UserContext'라는 이름의 새로운 Context 채널을 생성한다.
export const UserContext = React.createContext(null);
이 UserContext 객체는 이제 애플리케이션 전체에서 공유될 데이터 통로의 역할을 할 터였다.
두 번째 단계는, 이 채널을 통해 데이터를 ‘방송’하는 것이었다. 그는 최상위 컴포넌트인 <App>으로 돌아가 코드를 수정했다.
// App.js
import { UserContext } from './UserContext';
function App() {
const [currentUser, setCurrentUser] = useState({ name: 'Dan' });
// UserContext.Provider로 전체 앱을 감싼다.
// value prop을 통해 방송할 데이터를 지정한다.
return (
<UserContext.Provider value={currentUser}>
<Page />
</UserContext.Provider>
);
}
이제 <UserContext.Provider>로 감싸인 모든 자식 컴포넌트들은, 트리 구조의 어느 깊이에 있든 상관없이 currentUser 데이터에 접근할 수 있는 잠재적인 능력을 갖게 되었다.
마지막, 그리고 가장 극적인 단계가 남았다.
그는 Prop Drilling의 원인이었던 중간 컴포넌트들, <Page>, <Layout>, <Header>의 코드에서 currentUser prop을 모두 삭제했다. 더 이상 데이터를 전달하는 배관 역할을 할 필요가 없어진 것이다. 이 컴포넌트들은 마침내 자신과 관련 없는 데이터의 굴레에서 벗어나 깨끗해졌다.
그리고 마침내, 데이터가 정말로 필요했던 <UserAvatar> 컴포넌트를 열었다.
그는 클래스 시절의 복잡한 <UserContext.Consumer> 대신, 단 한 줄의 코드를 추가했다.
// UserAvatar.js
import React, { useContext } from 'react';
import { UserContext } from './UserContext';
function UserAvatar() {
// useContext 훅을 호출하여, 채널에서 데이터를 직접 꺼내온다!
const currentUser = useContext(UserContext);
if (!currentUser) return null;
return <img src={currentUser.avatarUrl} alt={currentUser.name} />;
}
const currentUser = useContext(UserContext);
이 한 줄의 코드는 마법과도 같았다.
<UserAvatar>는 자신의 부모가 누구인지, 얼마나 깊은 곳에 있는지 전혀 신경 쓰지 않았다. 그저 UserContext라는 채널에 접속해, 방송되고 있는 데이터를 직접 수신했을 뿐이다.
시연을 지켜보던 개발자들 사이에서 안도의 한숨과 함께 탄성이 터져 나왔다.
그들을 괴롭혔던 지루한 props 릴레이 경주가, Provider와 useContext라는 우아한 한 쌍의 조합으로 완벽하게 해결되는 순간이었다.
useContext는 훅의 철학을 명확하게 보여주었다.
복잡한 패턴(렌더 프롭)이나 중첩된 구조 대신, 필요한 것을 필요한 곳에서 직접 가져다 쓰는 간결하고 선언적인 방식.
이로써 리액트의 오래된 숙제였던 Prop Drilling은 사실상 해결되었다.
이제 개발자들은 더 이상 불필요한 데이터 배관 작업에 시간을 낭비하지 않고, 오직 컴포넌트의 본질적인 로직에만 집중할 수 있게 되었다.
훅의 기본 무기고가 점점 더 강력해지고 있었다.
하지만 팀은 곧, 이 새로운 도구들만으로는 해결하기 어려운, 더 복잡한 형태의 상태 관리 문제와 마주하게 될 터였다. 그 문제의 이름은 ‘상태의 폭발’이었다.


