useReducer는 "이전 상태와 액션을 받아 새 상태를 돌려주는" 리듀서(Reducer) 함수로 상태를 관리하는 훅이다. 이름처럼 Array.prototype.reduce의 아이디어를 시간축으로 늘린 것이다. 배열 요소 대신 시간순으로 들어오는 액션을 누적한다.
reduce: (acc, current) => newAcc
useReducer: (state, action ) => newState → 새 state면 리렌더type Action = { type: 'increment' } | { type: 'set'; payload: number }
function reducer(state: number, action: Action) {
switch (action.type) {
case 'increment': return state + 1
case 'set': return action.payload
}
}
const [count, dispatch] = useReducer(reducer, 0)
dispatch({ type: 'set', payload: 10 })useState와 고르는 기준
- 단순한 값(토글, 카운터), 서로 독립된 값 →
useState(React 상태 갱신) - 함께 바뀌는 상태 묶음(
isLoading·data·error) → reducer에서 한 번에 바꾼다. 불가능한 조합을 막으려면 상태 자체를 판별 유니언으로 모델링한다 - 변경 로직이 복잡할 때 → 로직이 컴포넌트에 흩어지지 않고 reducer 하나에 모인다
- "무슨 일이 일어났는지"가 중요할 때 →
setStatus('approved')대신dispatch({ type: 'APPROVE', approvedBy })처럼 의도를 남긴다. 명령을 객체로 만드는 커맨드 패턴과 닮았다 - reducer는 순수 함수(Pure Function)라서 컴포넌트 없이 단위 테스트하기 쉽다(자가 테스트 코드)
전역으로 키운 형태가 Redux다(Redux 이후의 상태 관리 선택).