[React] Props 지옥에서 벗어나는 법

2025. 5. 1. 10:54·JavaScript/React

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
'JavaScript/React' 카테고리의 다른 글
  • [React] Code Splitting (코드 스플리팅)
  • [React] Lazy Loading (지연 로딩)
  • [React] Context API
  • [React] 로컬스토리지는 왜 문제를 일으킬까?
츄핑
츄핑
    250x250
  • 츄핑
    개발로그
    츄핑
  • 전체
    오늘
    어제
    • 분류 전체보기
      • CS
        • 자료구조
        • 알고리즘
        • 운영체제
        • 네트워크
        • 데이터베이스
        • 인프라
        • Web
      • PS
        • 백준
      • JavaScript
        • React
        • Express
        • NestJS
        • TypeScript
        • Node.js
        • Electron
      • Java
        • Spring
      • Dart
        • Flutter
      • PHP
        • CodeIgniter
      • etc
        • 이산수학
        • 선형대수학
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    오블완
    티스토리챌린지
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.1
츄핑
[React] Props 지옥에서 벗어나는 법
상단으로

티스토리툴바