useReducer = 의도 붙은 useState.setX(newValue)호출이 컴포넌트에 흩뿌려지는 대신, 이름 붙은 action ({ type: 'INCREMENT' }) 을 dispatch 하고 단일 reducer 함수가 state 진화 방식 결정.
useState 에서 갈아탈 시점
컴포넌트가 useState 를 벗어났다는 표시 셋:
- 패턴으로 같이 업데이트 되는 state 값 여러 개 (예: 'status 가 error 로 뒤집히면 data 도 비우고 retry count 도 셋').
- 같은 논리적 이동이어야 할 부분 업데이트들이 핸들러 한 다스에 흩뿌려진 setter.
- Setter 호출로 묘사 하는 대신 — 'submit_started', 'submit_succeeded', 'submit_failed' — 처럼 이름 짓고 싶은 state 전환.
모양
const [state, dispatch] = useReducer(reducer, initialState). Reducer 는 순수 함수: (state, action) => nextState. 새 state 객체 반환해야 — in-place mutate 는 useState 와 같은 버그.
Discriminated-union action
useReducer 를 Track 2 lesson 5 의 discriminated union 과 결합: 각 action type 이 자기 타입 잡힌 payload 운반. Reducer 의 switch 가 action type narrow, TypeScript 가 모든 케이스 핸들링 보장.
useReducer 로 손이 안 가야 할 때
State 가 단일 숫자, 단일 문자열, 단일 boolean, 또는 무관 값 둘 — useState. useReducer 는 state 에 동사 (이름 붙은 방식으로 바꾸는 action) 가 있을 때 이김 — 명사 만 있을 때 아님.
Reducer 는 순수여야. 같은 state + action 주면 항상 같은 next state 반환.
fetch 호출 없음, 타임스탬프 있는 console.log 없음, Math.random() 없음. Side effect 는 이벤트 핸들러 (그 후 dispatch) 또는 effect 에 — 절대 reducer 안에 아님.