1. 쓰임새
- useState의 대체 함수
- reducer 로직과 initial state를 받아 현재 state와 dispatch를 반환
- dispatch 함수가 action을 전달하면, reducer 로직에 따라 state가 변경됨
// reducer 함수
(state, action) => newState;
// useReducer
const [state, dispatch] = useReducer(reducer, initialArg, init);
// 구체적으로 아래처럼 쓴다
const [state, dispatch] = useReducer(
reducer,
{count: initialCount}
);
2. useState 대신 useReducer를 쓰기 좋은 경우
- 많은 분기를 사용하는 등 복잡한 로직을 만들 때
- 다음 state가 이전 state에 의존적일 때
3. 효과
- 콜백 함수 대신 dispatch를 전달하기 때문에 컴포넌트 성능을 최적화할 수 있음
4. useState vs useReducer
useState를 쓴 경우
function Counter({initialCount}) {
const [count, setCount] = useState(initialCount);
return (
<>
Count: {count}
<button onClick={() => setCount(initialCount)}>Reset</button>
<button onClick={() => setCount(prevCount => prevCount - 1)}>-</button>
<button onClick={() => setCount(prevCount => prevCount + 1)}>+</button>
</>
);
}
useReducer를 쓴 경우
const initialState = {count: 0};
function reducer(state, action) {
switch (action.type) {
case 'increment':
return {count: state.count + 1};
case 'decrement':
return {count: state.count - 1};
default:
throw new Error();
}
}
function Counter() {
const [state, dispatch] = useReducer(reducer, initialState);
return (
<>
Count: {state.count}
<button onClick={() => dispatch({type: 'decrement'})}>-</button>
<button onClick={() => dispatch({type: 'increment'})}>+</button>
</>
);
}