리액트에서 상태를 관리할 때, 조금 더 복잡한 상태관리를 위해서는useState가 아닌 useReducer를 사용한다.
기본적인 useReducer의 형태는 다음과 같다.
const [state, dispatch] = useReducer(reducer, initialState);
- state는 사용할 상태
- dispatch 는 액션을 발생시키는 함수 (다음과 같이 사용한다. dispatch({ type: 'INCREMENT' }))
- reducer: reducer함수
- initialState: 상태의 초깃값
즉, dispatch함수를 통해 액션을 하면, reducer함수가 이 액션에 따라 상태를 변경하는 것이다.
const countReducer = (oldNum, action) => {
if(action.type === 'UP') {
return oldNum + action.number
} else if (action.type === 'RESET') {
return 0
} else if (action.type ==='DOWN') {
return oldNum - action.number
}}
액션 객체가 가진 type에 따라 상태를 변경한다. 현재 객체 상태를 oldNum으로 전달받으며, 이 상태가 액션 객체의 type에 따라 변화하는 것이다.
const [num, numDispatch] = useReducer(countReducer,0);
const onUp = () => {
numDispatch({type: "UP", number: number});
};
const onDown = () => {
numDispatch({type: "DOWN", number: number})
};
const onZero = () => {
numDispatch({type: "RESET", number: number})
}
import { useState, useReducer } from 'react';
function App() {
const countReducer = (oldNum, action) => {
if(action.type === 'UP') {
return oldNum + 1
} else if (action.type === 'RESET') {
return 0
} else if (action.type ==='DOWN') {
return oldNum - 1
}}
const [num, numDispatch] = useReducer(countReducer,0);
const onUp = () => {
numDispatch({type: "UP"});
};
const onDown = () => {
numDispatch({type: "DOWN"})
};
const onZero = () => {
numDispatch({type: "RESET"})
}
return (
<div>
<input type="button" value='-' onClick={onDown}/>
<input type="button" value='0'onClick={onZero}/>
<input type="button" value='+' onClick={onUp}/>
{num}
</div>
);
}
export default App;
위 함수는 + 와 - 버튼을 눌러서 number라는 상태를 변화시키고 이를 보여주는 함수이다. +버튼을 눌렀을 경우 onDown함수가 실행되면서 numDispatch함수를 실행시키는데, 이때 전달되는 액션은 'UP'이며, 액션 객체를 전달받은 countReducer함수는 num상태의 값에 1을 더한다.