id, title, category, status, source_trust_level, verification_status, created_at, updated_at, tags, tech_stack, applied_in, aliases
| id |
title |
category |
status |
source_trust_level |
verification_status |
created_at |
updated_at |
tags |
tech_stack |
applied_in |
aliases |
| react-reducer-usereducer |
useReducer — 복잡 상태 전이 |
Coding |
draft |
B |
conceptual |
2026-05-09 |
2026-05-09 |
| react |
| reducer |
| state-machine |
| vibe-coding |
|
| language |
applicable_to |
| TypeScript / React 18+ |
|
|
|
| useReducer |
| dispatch |
| action type |
|
useReducer — 복잡 상태 전이
여러 setState 호출이 한 묶음으로 일어나거나, 다음 상태가 이전 상태에 의존하면 useReducer. action 을 discriminated union 으로 정의하면 state 전이가 곧 state machine.
📖 핵심 개념
(state, action) => state 순수 함수.
- 호출자는 dispatch(action) — UI 와 비즈니스 로직 분리.
- 테스트 = reducer 함수만 단위 테스트.
💻 코드 패턴
🤔 의사결정 기준
| 상황 |
useReducer |
useState |
| 상태 필드 1~2개 |
❌ |
✅ |
| 다음 상태가 여러 필드 동시 변경 |
✅ |
useState 도 가능하지만 reducer 가 명확 |
| 상태 머신 (idle/loading/success) |
✅ |
❌ |
| 깊은 자식이 dispatch 만 알면 됨 |
✅ (Context 로 dispatch 만 내려) |
❌ |
| 외부 라이브러리 (Zustand) 더 나은 경우 |
글로벌 상태면 외부 store |
useReducer 는 컴포넌트 단위 |
❌ 안티패턴
- action 에 함수/promise 넣기: action 은 직렬화 가능 데이터. side effect 는 effect 안에서 dispatch.
- action.type 을 string union 안 만듦: typo 가능. union 으로.
- reducer 안에서 fetch / setTimeout: pure 깨짐. effect 가 dispatch.
- state 직접 mutate (
state.foo = 1): React 가 변화 감지 못 함. 항상 새 객체 반환.
- switch 에 default 없음: 새 action 추가 시 누락 모름. assertNever 패턴.
🤖 LLM 활용 힌트
- "복잡 상태 전이 → discriminated union state + action, exhaustive switch" 명시.
- Immer 사용 시 reducer 안에서 mutation OK (immer 가 immutable 변환).
🔗 관련 문서