const [state, dispatch] = useReducer(reducer, initialArg, init?)
Parameter
reducer: state가 업데이트되는 방식을 지정하는 reducer 함수이다.
state와 action을 arguments로 받고 nextState를 반환해야 한다.state와 action은 어떤 Type이든 가능하다.initialArg: 초기 state를 계산하는 값. 모든 Type이 가능하다. 초기 state를 계산하는 방식은 다음 init argument에 따라 달라진다.
init(optional): 초기 상태를 반환해야 하는 초기화 함수
이 함수가 명시되지 않은 경우 초기 state는 initialArg로 설정
반면, 이 함수가 명시되었다면 초기 state는 init(initialArg)를 호출한 결과로 설정됩니다.
공식문서의 설명은 굉장히 긴데 이걸 쉽게 풀어 설명하면 다음과 같다.
Summary
reducer:state를 업데이트하는 함수
initialArg: 초기state로 사용될 값 (또는 초기화 함수에 전달할 인자)
init(optional): 초기state를 가공하거나 계산해서 반환하는 함수
Returns
useReducer는 2개의 값을 가진 배열을 return한다.
1. state (The current state, 현재 상태)
2. dispatch: dispatch함수는 state를 다른 값으로 업데이트하고 다시 렌더링을 트리거 할 수 있다.
Caveats
3가지 주의사항을 한번 알아보자 ↓

1. useReducer는 Hook이므로 컴포넌트의 최상위 레벨이나 커스텀 훅 안에서만 사용이 가능하다. 반복문 or 조건문 안에서는 호출 불가능,
2. dispatch는 Effect dependency에서 제거해도 안전하다. 만약 포함하더라도 Effect가 실행되지 않는다
3. Strict 모드에 대한 애기 (두 번 호출)
dispatch functiondispatch는 useReducer에서 반환되는 함수로, state를 업데이트하고 리렌더링을 트리거, 이 때 dispatch의 argument로 action 객체를 인자로 넘겨야 한다.
const [state, dispatch] = useReducer(reducer, { age: 42 });
function handleClick() {
dispatch({ type: 'incremented_age' });
// ...
Parameter
action:
action은 보통 type이라는 속성을 가진 객체이며, 선택적으로 추가 정보를 담는 다른 속성들을 포함할 수 있다.메모
Redux에서도 useReucer의 형태를 따라 만들었다고 한 문서를 봤는데
진짜 거의 비슷하네
Caveats
dispatch에도 3가지 주의 사항이 있다. ↓

dispatch 함수는 다음 렌더링을 위한 state variable만을 업데이트 한다.useState와 마찬가지로,state 업데이트가 일어났다고 해서 즉시 변경된 값이 반영되는 것이 아니라 다음 렌더링 이후에 반영된다는 점에서 동일state를 비교할 때 Object.is를 통해 비교하며 변경사항이 없을 경우 리렌더 X state 업데이트를 batch 처리useState에서 나온 Caveats와 동일import { useReducer } from 'react';
function reducer(state, action) {
if (action.type === 'incremented_age') {
return {
age: state.age + 1
};
}
throw Error('Unknown action.');
}
export default function Counter() {
const [state, dispatch] = useReducer(reducer, { age: 42 });
return (
<>
<button onClick={() => {
dispatch({ type: 'incremented_age' })
}}>
Increment age
</button>
<p>Hello! You are {state.age}.</p>
</>
);
}
useReducer는useState와 매우 흡사하나
useReducer는 이벤트 핸들러에 흩어져 있던 state 변경 로직을 컴포넌트 외부의 하나의 함수(reducer)로 분리할 수 있게 해준다.
useStatevsuseReducer
useReducer에도 단점은 존재
- Code size:
useReducer를 사용하면reducer함수와dispacth함수를 모두 작성하기에 코드 사이즈가 커진다. 하지만, 여러 이벤트 핸들러가 비슷한 방식으로state를 수정하는 경우useReducer를 사용하면 코드 크기를 줄일 수 있다.
- Readability(가독성):
state업데이트가 단순할 때는 useState가 읽기 쉽고 간결하다.
하지만 업데이트 로직이 복잡해지고 컴포넌트 코드가 길어지면 가독성이 떨어질 수 있다.
이럴 때useReducer는 "어떻게 상태를 업데이트할지(how)"와 "무슨 일이 발생했는지(what happened)"를 명확히 분리해주어, 코드 구조를 더 깔끔하게 만들어준다.
- Debugging:
useReducer를 각 함수에 로깅을 할 수 있어서 디버깅에 용이
- Testing: reducer는 순수 함수이고 이것은 컴포넌트에 영향이 없기에 독립적인 테스트에 용이
- Personal preference: 개인의 선호에 맞춰서 useState와 useReducer를 사용하면 된다. 둘은 동일하다.
React 팀은
state업데이트를 맞이할 때 버그가 잦고 코드 구조가 복잡할 때useReducer사용을 권장
모든 상황에 쓸 필요는 없으며,useState와 혼용하거나 함께 사용하는 것도 가능한다고 한다.

이것은 불변성에 관한 애기로 직접적으로상태를 변경시키지 말라는 것