useReducer란 useState를 대체하는 함수로, useState의 심화 버전이다.
useReducer는 reducer를 이용하여 컴포넌트의 상태 로직을 관리한다.
action을 넘겨준다. action은 state를 변경하는 액션을 의미한다.const [ state, dispatch ] = useReducer(reducer, initalState, init);
reducer 함수를 실행시키며, action객체를 인자로 받는다.
즉, reducer 함수가 실행 ( state를 업데이트하는 로직을 실행) 되도록,요구하는 행위
이때요구의 내용을action이라고 명명한다.
즉, action을 사용하여 state의 업데이트를 일으킨다.
- action: 어떤 행동인지를 나타내는 type 속성과 해당 행동과 관련된 데이터(payload)를 담고 있다.
dispatch 함수에 의해 실행되며, 컴포넌트 외부에서 state를 업데이트하는 로직을 담당한다.
함수의 인자로는 state와 action을 받게 된다.
state와 action을 활용하여 새로운 state를 반환한다.
즉, action의 내용대로 state를 업데이트함


import React, { useReducer } from "react";
//컴포넌트 밖에서 reducer 함수를 정의한다.
function reducer(state, action) {
switch (action.type) {
case "INCREMENT":
return { count: state.count + action.payload };
case "DECREMENT":
return { count: state.count - action.payload };
default:
throw new Error("unsupported action type: ", action.type);
}
}
const Counter = () => {
const initialState = { count: 0 };
const [state, dispatch] = useReducer(reducer, initialState);
return (
<>
<h2>{state.count}</h2>
<button onClick={() => dispatch({ type: "INCREMENT", payload: 1 })}>
증가
</button>
<button onClick={() => dispatch({ type: "DECREMENT", payload: 1 })}>
감소
</button>
<button onClick={() => dispatch({ type: "kkkkkkkkk", payload: 1 })}>
에러
</button>
</>
);
};
export default Counter;
이때, init함수를 세 번째 인자로 전달하면 초기 state는 init에 설정된다.
import React, { useReducer } from "react";
function init(initialState) {
return { count: initialState };
}
function reducer(state, action) {
switch (action.type) {
case "INCREMENT":
return { count: state.count + action.payload };
case "DECREMENT":
return { count: state.count - action.payload };
case "RESET":
//init 함수 사용
return init(action.payload);
default:
throw new Error("unsupported action type: ", action.type);
}
}
const Counter = ({ initialCount }) => {
const [state, dispatch] = useReducer(reducer, initialCount, init);
return (
<>
<h2>{state.count}</h2>
<button onClick={() => dispatch({ type: "RESET", payload: 0 })}>
초기화
</button>
<button onClick={() => dispatch({ type: "INCREMENT", payload: 1 })}>
증가
</button>
<button onClick={() => dispatch({ type: "DECREMENT", payload: 1 })}>
감소
</button>
<button onClick={() => dispatch({ type: "kkkkkkkkk", payload: 1 })}>
에러
</button>
</>
);
};
export default Counter;
useReducer의 목적은 복잡한 형태의 state를 사전에 정의된 dispatch로만 수정할 수 있게 하여, state 값에 대한 접근은 컴포넌트에서만 가능하게 하고,
업데이트하는 방법에 대한 상세 정의를 컴포넌트 밖으로 분리한다.
이를 통해, state의 업데이트를 미리 정의해 둔 dispatcher로만 제한한다.
즉, state값을 변경하는 시나리오를 제한적으로 두고 이에 대한 변경을 빠르게 확인할 수 있게끔 하는 것이 useReducer의 목적이다.
여러 개의 하위값을 가지는 state의 경우의 수가 많아지면 비슷한 성격의 state를 묶어 useReducer로 관리하는 것이 효율적이다.
init 함수가 없다면 두 번째 인수로 넘겨받은 기본값을 사용하게 된다.
init 함수가 있다면 useState에 함수를 넣은 것과 같은 이점을 누릴 수 있고, state에 대한 초기화가 필요할 때 reducer에서 재사용할 수 있다.

