useState와 같이 상태를 관리하는 또 다른 방법이다. useReducer를 사용하면 컴포넌트의 상태 업데이트 로직을 컴포넌트에서 분리시킬 수 있다. 상태 업데이트 로직을 컴포넌트 바깥에 작성 할 수도 있고, 심지어 다른 파일에 작성 후 불러와서 사용할 수도 있다.
현재 상태와 액션 개체를 파라미터로 받아와서 새로운 상태를 반환해 주는 함수. 여기서 반환하는 상태는 곧 컴포넌트가 지닐 새로운 상태이다.
function reducer(state, action) {
// 새로운 상태를 만드는 로직
// const nextState = ...
return nextState;
}
action
업데이트를 위한 정보를 가지고 있다. action 객체의 형태는 자유이다.
dispatch({액션에 대한 정보}) 이런 형태로 사용한다.
// 카운터에 1을 더하는 액션
{
type: 'INCREMENT'
}
// 카운터에 1을 빼는 액션
{
type: 'DECREMENT'
}
// input 값을 바꾸는 액션
{
type: 'CHANGE_INPUT',
key: 'email',
value: '[email protected]'
}
형태는 다음과 같다.
const [state, dispatch] = useReducer(reducer, initialState);
state가 바로 컴포넌트에서 사용하는 상태이고, dispatch는 액션을 발생시키는 함수이다.
useReducer의 첫번째 파라미터에는 reducer 함수를, 두번째 파라미터는 초기 상태를 넣는다.
reducer 함수를 통해서 state의 값이 action에 따라 어떻게 변화하는지를 리턴하고, 그 리턴 값이 바로 새 state의 값이 된다.
Counter.js
useState 사용 시
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;