상태를 업데이트하기 위해서 useState를 사용하는 방법이외에 다른 방법이 있는데 그것이 바로 useReducer이다. 이 Hook 함수를 사용하면 컴포넌트의 상태 업데이트 로직을 컴포넌트에서 분리할 수 있다. 또한 상태 업데이트 로직을 컴포넌트의 외부에 작성할 수 있고 다른 파일에 작성한 후에 불러와서 사용할 수도 있다.
import React, { useState } from 'react';
function Counter() {
const [number, setNumber] = useState(0);
const onIncrease = () => {
setNumber(prevNumber => prevNumber + 1);
};
const onDecrease = () => {
setNumber(prevNumber => prevNumber - 1);
};
return (
<div>
<h1>{number}</h1>
<button onClick={onIncrease}>+1</button>
<button onClick={onDecrease}>-1</button>
</div>
);
}
export default Counter;
위의 코드는 useState
를 사용한 Counter 컴포넌트인데 useReducer
를 사용하면 아래와 같은 코드로 변경할 수 있고 동일하게 동작한다.
import React, { useReducer } from 'react';
function reducer(state, action) {
switch (action.type) {
case 'INCREMENT':
return state + 1;
case 'DECREMENT':
return state - 1;
default:
return state;
}
}
function Counter() {
const [number, dispatch] = useReducer(reducer, 0);
const onIncrease = () => {
dispatch({ type: 'INCREMENT' });
};
const onDecrease = () => {
dispatch({ type: 'DECREMENT' });
};
return (
<div>
<h1>{number}</h1>
<button onClick={onIncrease}>+1</button>
<button onClick={onDecrease}>-1</button>
</div>
);
}
export default Counter;
useReducer를 사용한 부분을 자세하게 보면,
const [state, dispatch] = useReducer(reducer, initialState);
state
는 동일하게 컴포넌트에서 사용하는 상태를 의미하고 dispatch
는 상태를 변경하는 액션(action)을 발생시키는 함수이다. useReducer
의 첫 번째 매개변수는 reducer 함수이고 두 번째 매개변수는 초기값이다.
어떤 상황에서 useState
나 useReducer
를 사용해야 할지 고민이 생길 수 있는데 딱히 정해진 정답은 없다. 하지만 일반적으로 컴포넌트에서 관리하는 상태 값이 많아져 구조가 복잡해질 경우에 useReducer
로 관리하는 편이라고 한다.