안녕하세요. RyuWoong입니다.
이번에 이야기의 주제는 useReducer입니다.
상태관리 라이브러리인 Redux를 사용해 보셨으면 꽤 친숙한 Hook 이실텐데요.
한 번 알아보러 가봅시다.
useReducer
useReducer는 상태 관리 Hook 입니다. useState를 대체할 수 있는 Hook인 것이죠!
🤔 다수의 하윗값을 포함하는 복잡한 정적 로직을 만드는 경우나 다음 state가 이전 state에 의존적인 경우에 보통
useState보다 useReducer를 선호합니다. useReducer는 자세한 업데이트를 트리거 하는 컴포넌트의 성능을 최적화할 수 있게 합니다.
공식 문서에서는 useReducer를 어떤 때에 사용하는 것이 좋은지 위와 같이 말하고 있습니다.
어떤 의미인지 코드와 함께 보도록 하겠습니다.
아래 코드는 공식 문서에 있는 코드이며, useState 예제를 useReducer를 사용하여 수정한 것입니다.
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();
}
}
function Counter() {
const [state, dispatch] = useReducer(reducer, initialState);
return (
<>
Count: {state.count}
<button onClick={() => dispatch({type: 'decrement'})}>-</button>
<button onClick={() => dispatch({type: 'increment'})}>+</button>
</>
);
}
코드를 보면 dispatch 함수로 정적인 로직을 실행 시킬 수 있습니다. type: 'decrement' 또는type: 'increment' 로 미리 Reducer에 설계한 내용대로 동작하게 됩니다. 그리고 이전 상태, 즉 count의 값이 이전 값 + 1 또는 -1 으로 계산됩니다.
초기 값 설정하기
초기 값 설정은 쉽습니다. useReducer내 두번째 인자로 넣어주면 됩니다.
const [state, dispatch] = useReducer(reducer,{count: initialCount});
⚠️ React에서는 Reducer의 인자로써 state = initialState와 같은 초기값을 나타내는, Redux에서는 보편화된 관습을 사용하지 않습니다. 때때로 초기값은 props에 의존할 필요가 있어 Hook 호출에서 지정되기도 합니다. 초기값을 나타내는 것이 정말 필요하다면 useReducer(reducer, undefined, reducer)를 호출하는 방법으로 Redux를 모방할 수는 있겠지만, 이 방법을 권장하지는 않습니다.
초기 값 지연
초기 값을 함수 내에서 계산 후 적용되도록 설정할 수 있습니다. 이걸 지연이라고 표현하는거 같네요.
useReducer 세번째 인자로 init을 넣어 initialCount 값은 init 함수를 거쳐 초기화 됩니다.
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();
}
}
function Counter({initialCount}) {
const [state, dispatch] = useReducer(reducer, initialCount, init);
return (
<>
Count: {state.count}
<button
onClick={() => dispatch({type: 'reset', payload: initialCount})}>
Reset
</button>
<button onClick={() => dispatch({type: 'decrement'})}>-</button>
<button onClick={() => dispatch({type: 'increment'})}>+</button>
</>
);
}
dispatch 회피
이건 useState의 setState처럼, 현재와 똑같은 State 값을 반환한다면 React는 자식을 리렌더링하거나 effect를 발생시키지 않습니다.
생각보다 크게 어렵지 않죠? Redux에서 몇번 접한 뒤라면 이해가 쉬웠을 수도 있을 거라 생각합니다!
Redux외에도 Context API를 사용할 때도 함께 종종 사용하기도 합니다. 이건 다음번에 알아보도록 하죠!
오늘은 여기까지 입니다. 다음번엔 Context API를 이야기 해보겠습니다.
'Front-End > React' 카테고리의 다른 글
[React] Custom Hook .09 (0) | 2023.02.14 |
---|---|
[React] Context API .08 (0) | 2023.02.05 |
[React.js] Hooks - useRef .06 (0) | 2021.01.20 |
[React.js] Hooks - useEffect .05 (0) | 2021.01.05 |
[React.js] Hooks - useState .04 (0) | 2020.12.20 |
삽질의 기록과 일상을 남기는 블로그입니다. 주로 React Native를 다룹니다.
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!