state 를 관리하고 업데이트 하는 hook 인 useState 를 대체 할 수 있는 hook 입니다.
즉, useReducer 는 useState 처럼 state 를 관리하고 업데이트 할 수 있는 hook 입니다.
Redux 가 돌아가는 구조랑 비슷함 (Observer 패턴)
//useState를 이용해 구현한 Counter
import React, { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0);
const increment = () => {
setCount(count + 1);
};
const decrement = () => {
setCount(count - 1);
};
return (
<div>
<p>Count: {count}</p>
<button onClick={increment}>Increment</button>
<button onClick={decrement}>Decrement</button>
</div>
);
}
export default Counter;
// useReducer를 사용해 구현한 카운터
const [state, dispatch] = useReducer(reducer, initialArg, init);
// (state, action) => newState 의 형태로 reducer를 받음.
// 상태를 관리하려는 공통 조상부모 컴포넌트에서 선언함.
const initialState = {count: 0};
function reducer(state, action) {
switch (action.type) {
case 'increment':
return {count: state.count + 1};
case 'decrement':
return {count: state.count - 1};
default:
throw new Error();
}
}
// reducer 파일을 따로 분리
function Counter() {
const [state, dispatch] = useReducer(reducer, initialState);
return (
<>
Count: {state.count}
<button onClick={() => dispatch({type: 'decrement'})}>-</button>
<button onClick={() => dispatch({type: 'increment'})}>+</button>
</>
);
}
function init(initialCount) {
return {count: initialCount};
}
function reducer(state, action) {
switch (action.type) {
case 'increment':
return {count: state.count + 1};
case 'decrement':
return {count: state.count - 1};
case 'reset':
return init(action.payload);
default:
throw new Error();
}
}
state와의 차이점 => 상태가 복잡해지거나 커지면, reducer를 사용해서 효율적인 코드를 작성할 수 있음.
state와 비교했을때 장점 => reducer 로직의 분리(비즈니스 로직 분리가능)
다수의 하윗값을 포함하는 복잡한 정적로직을 만들거나, 다음 state가 이전 state에 의존적인 경우 사용이 선호됨 => callback대신 dispatch를 통해 상태를 update함
ref)
https://choi-hyunho.tistory.com/196
https://ko.legacy.reactjs.org/docs/hooks-reference.html#usereducer
https://goddaehee.tistory.com/311
https://velog.io/@goldbear2022/setInterval-%ED%8A%B9%EC%A7%95%EA%B3%BC-useInterval