Skip to content

전역 상태 관리

-Passing Data Deeply with Context 여러 컴포넌트에서 상태를 사용해야 할 때 === 전역 상태 관리가 필요할 때 사용할 수 있는 도구가 필요해짐

React의 상태를 관리하는 방법

내부

  • useState
  • Context API

외부


Props Drilling

propsdrilling 🔄 용어 매핑

source → state owner / source of truth (상태가 처음 선언되고 보관되는 곳)

reader → consumer (상태를 props/context로 읽기만 하는 컴포넌트)

writer → updater / dispatcher (상태를 변경하는 setState 호출자)

bridge → intermediate / middle component (스스로 쓰진 않고 단순히 props를 전달만 하는 중간 다리 역할)

App → state owner (source of truth)

Child3 → consumer

Child6 → updater

Child2 → intermediate (중간 전달자)

  • app에서 counter 상태를 만들고 관리한다.
  • 1을 거쳐서 3까지 상태를 내려주고 상태를 띄운다
  • 상태를 변경하는 경우 2를 거쳐 6까지 상태를 내려주고 상태 변경 함수를 적어주고 상태를 변경한다.
  • 그리고 리렌더링 되어야하는 부분은 3에서만 일어나면 되지만, 지금 상태에서는 모든 컴포넌트가 다 리렌더링이 발생하고 있다. 즉, 불필요한 리렌더링이 발생하고 있다. 상태를 관리하는 app이 리렌더링 되고 있는 것
bash
📦 props-drilling-demo
└─ src
   ├─ App.jsx              # 상태 선언, 트리 구성 (counter, setCounter)
   └─ App.styled.js       # 역할(role)별 색상/테두리 스타일
scss
🧩 Component Tree (with roles & props)

App [$role=source]
└─ Outer
   ├─ Legend
   └─ Container [$role=source]
      └─ Component [$role=source]  "Props Drilling"
         ├─ Child1  (props: counter)                [$role=reader]
         │  └─ Component [$role=reader]
         │     ├─ Child3 (props: counter)           [$role=reader]  -> 화면에 counter 표시
         │     └─ Child4                             [-]            -> 상태 미사용
         └─ Child2  (props: counter, setCounter)    [$role=bridge]  -> 중계자
            └─ Component [$role=bridge]
               ├─ Child5                             [-]            -> 상태 미사용
               └─ Child6 (props: counter, setCounter)[$role=writer] -> 버튼 클릭 시 +1

🧩 Component Tree (roles & received props)

App [$role=source]  (state: counter, setCounter)
└─ Outer
   ├─ Legend
   └─ Container [$role=source]
      └─ Component [$role=source]  "Props Drilling"
         ├─ Child1 (props: counter)                             [$role=reader]
         │  └─ Component [$role=reader]  "Child1"
         │     └─ Container
         │        ├─ Child3 (props: counter)                   [$role=reader]  → 화면에 표시
         │        │  └─ Component [$role=reader] "Child3 : {counter}"
         │        └─ Child4 (no props)                         [-]
         │           └─ Component "Child4"
         └─ Child2 (props: counter, setCounter)                 [$role=bridge]
            └─ Component [$role=bridge] "Child2"
               └─ Container
                  ├─ Child5 (no props)                         [-]
                  │  └─ Component "Child5"
                  └─ Child6 (props: counter, setCounter)       [$role=writer]
                     └─ Component [$role=writer] "Child6"
                        └─ button onClick → setCounter(counter + 1)
diff
🔁 Data/Action Flow

STATE OUT (↓)
- counter:     App → Child1 → Child3   | App → Child2 → Child6
- setCounter:  App ───────────────→ Child2 → Child6

ACTION UP (↑)
- onClick in Child6 → setCounter(counter + 1) → App re-render
  → 읽는 컴포넌트(Child1/Child3)와 쓰는 컴포넌트(Child6)가 함께 업데이트
css
🎨 Role Legend (styled-components)

source : bg #192524, border #3AA097, text #E6E7EB  → 상태의 출발점
reader : bg #1B1C2A, border #7E86F9, text #E6E7EB  → 읽기 전용 표시
bridge : bg #262015, border #DCAB70, text #E6E7EB  → 중간 전달(직접 사용 X)
writer : bg #26181B, border #F291A0, text #E6E7EB  → 상태 변경 주체
🎨 Role Legend (styled-components)
source → 상태의 출발점      : bg #192524, border #3AA097
reader → 읽기 전용 소비자   : bg #1B1C2A, border #7E86F9
bridge → 중간 전달자         : bg #262015, border #DCAB70
writer → 상태 변경 주체      : bg #26181B, border #F291A0

🔁 Data Flow (down) / Action Flow (up)

counter ↓ : App
  → Child1 → Child3 (표시)
  → Child2 → Child6 (버튼에 현재 값 전달)

setCounter ↓ : App
  → Child2 → Child6

onClick ↑ : Child6
  → setCounter(counter + 1)  → App 재렌더
    → Child1/Child3(Reader)와 Child6(Writer) 업데이트
diff
📌 Key Takeaways

- Props Drilling: 필요 없는 중간(bridge)까지 props가 통과해야 함.
- Reader/Writer 분리: Child3는 읽기만, Child6는 쓰기 전용.
- 개선 포인트: Context/상태관리 라이브러리로 bridge 제거 가능.
📌 핵심 포인트
- Props Drilling 데모: Child2는 직접 쓰지 않지만 props를 ‘전달’만 하는 bridge.
- Reader/Writer 분리: Child3는 읽기만, Child6는 쓰기만 담당.
- 개선 여지: Context/전역 상태로 bridge 경로를 제거 가능.

Context API

사용법

  1. createContext로 전역 상태 만들기
  2. Provider로 전역 상태 연결해 주기
  3. useContext로 전역 상태 가져와 주기