React를 사용하다 보면, 아래와 같은 코드를 본 적 있을 겁니다
<GrandParent>
<Parent>
<Child>
<GrandChild data={userInfo} />
</Child>
</Parent>
</GrandParent>
이렇게 깊게 중첩된 컴포넌트 구조에서 props를 계속 전달해야 하는 상황을 흔히 “props drilling”이라고 부릅니다. 이 문제는 컴포넌트 재사용성 저하, 유지보수성 하락, 복잡성 증가로 이어지며, 개발자의 정신 건강에 매우 안 좋습니다.
props 지옥이란?
props 지옥 = 여러 컴포넌트 레이어를 거쳐 데이터를 직접 전달해야 하는 상황을 비유적으로 표현한 용어
예시 상황
function App() {
const user = { name: "Alice" };
return <Parent user={user} />;
}
function Parent({ user }) {
return <Child user={user} />;
}
function Child({ user }) {
return <GrandChild user={user} />;
}
function GrandChild({ user }) {
return <div>Hello, {user.name}</div>;
}
App → Parent → Child → GrandChild
이렇게 매번 user
를 넘겨줘야 하죠.
문제점
- 중간 컴포넌트는
user
를 사용하지 않는데도 props로 받아야 함 - props 구조 변경 시 상위/하위 컴포넌트 모두 수정 필요
- 테스트 어려움, 재사용성 저하
props drilling의 문제점
문제 | 설명 |
유지보수성 ↓ | 중간 컴포넌트에서 필요 없는 props도 받아야 함 |
가독성 ↓ | 데이터 흐름이 복잡해짐 |
재사용성 ↓ | 컴포넌트가 특정 데이터에 종속되게 됨 |
테스트 어려움 | 원하는 데이터만 테스트하기 힘듦 |
해결 방법
1) React Context API
React 내장 기능으로 전역 데이터 공급자 역할
컴포넌트 트리 중간 단계를 생략 가능
const UserContext = createContext();
function App() {
const user = { name: "Alice" };
return (
<UserContext.Provider value={user}>
<Parent />
</UserContext.Provider>
);
}
function GrandChild() {
const user = useContext(UserContext);
return <div>Hello, {user.name}</div>;
}
2) 상태 관리 라이브러리
- Redux: 큰 규모 앱에 적합 (미들웨어, DevTools 등 지원)
- Recoil: React 친화적, 간단한 상태 분리 가능
- Zustand: 훨씬 간결하고 lightweight
- Jotai, MobX 등도 있음
이들은 전역 상태 저장소를 통해 props 전달을 생략시킵니다.
3) Composition을 활용한 해결
간혹 props 대신 children에 콜백을 넘기거나
render props 형태로 처리할 수도 있습니다.
<Parent>
{(user) => <GrandChild user={user} />}
</Parent>
이 방식은 props를 직접 넘기진 않지만,
복잡성을 감추는 정도라서 Context보다 깔끔하진 않습니다.
예제: Context API로 props 지옥 탈출
// 1. context 생성
const ThemeContext = createContext();
// 2. provider로 감싸기
function App() {
const theme = "dark";
return (
<ThemeContext.Provider value={theme}>
<Layout />
</ThemeContext.Provider>
);
}
// 3. 하위 컴포넌트에서 바로 사용
function Layout() {
return <Header />;
}
function Header() {
const theme = useContext(ThemeContext);
return <h1>Current Theme: {theme}</h1>;
}
중간에 아무런 props 없이도 데이터를 가져올 수 있음 → 매우 간결
정리
방법 | 장점 | 단점 |
Context API | 간단, 내장 기능, 중소규모 앱에 적합 | 재렌더링 문제 발생 가능, 깊은 구조엔 주의 |
Redux / Zustand | 대규모 상태 관리에 적합, DevTools | 학습 곡선 있음, 설정 필요 |
Composition | 유연성 | 패턴을 잘 모르면 복잡해짐 |
마무리
props 지옥은 초보자든 숙련자든 반드시 한 번은 겪는 경험입니다.
그러나 React는 다양한 도구를 통해 이 문제를 유연하게 해결할 수 있습니다.
props drilling이 느껴진다면, 다음을 고려하세요
- 반복적인 props → Context API 고려
- 상태가 크고 다양함 → 상태 관리 라이브러리 도입
- 단순한 재사용성 → composition 고려
728x90