정의
useState의 대체 함수이다. (state, action) => newState의 형태로 reducer를 받고 dispatch 메서드와 짝의 형태로 현재 state를 반환 - 공식 문서
const [state, dispatch] = useReducer(reducer, initialArg, init)
특징
redux의 reducer와 비슷하게 동작한다. 또한 init에 state 생성 함수를 전달함으로써 초기화 지연이 가능하다.
dispatch의 회피 - Reducer Hook에서 현재 state와 같은 값을 반환하는 경우 자식을 리렌더링, effect 발생시키지 않고 이것들을 회피
활용
브라우저 상에서 이미지를 편집하는 서비스를 개발하고 있다. 배경 이미지를 설정하고, 다른 이미지나 텍스트를 삽입하고 수정할 수 있는데,
이를 위해서 각 이미지, 텍스트 컴포넌트들의 속성을 상태로 관리한다.
images = [
{
id: 12,
src: "asdf",
x: 12,
y: 13,
width: 232,
height: 540,
...
},
...
]
useState를 활용해서 각 컴포넌트들의 속성을 변경하려면
// 변경하고자 하는 컴포넌트 : target
const newState = state.slice()
const targetIdx = images.findIndex(e => e.id === target.id)
newState[targetIdx][property] = newValue
이런식으로 짜는데, 가독성이 조금 떨어지고 복잡하다.
물론 부모 컴포넌트에서 이를 함수로 만들어서 밑으로 내려주면 되긴한다.
const changeProperty = (state, property, value) => {
//...위에 내용
return newState
}
<Childern changeProperty={changeProperty} />
하지만 이렇게 하면 부모컴포넌트의 코드 양이 많아지고 상태 관리하는 부분이 많게 된다.
상태 관리하는 부분만 따로 빼놓은 것이 useReducer라고 보면된다.
function reducer(state,action) {
let newState = state.slice()
switch(actiont.type){
case 'CHANGE__PROPERTY':
// ...속성 변경
break
// ...생략
}
return newState
}
function Component(){
const [state, dispatch] = useReducer(reducer,initialState)
// ...생략
dispatch({
type: "CHANGE__PROPERTY",
id: targetId,
property: p,
value: v
})
}
이런식으로 코드가 깔끔해지고 분리해놨기 때문에 나중에 유지 보수가 편해진다.
요약
useReducer는 상태 변경하는 로직이 복잡하거나 이전 상태에서 조금만 바뀌거나, 객체들의 배열의 상태를 변경하는 경우에 매우 유용하다.
상태관리 로직이 따로 분리되어 있어 유지 보수에도 좋고 가독성이 좋다.
'프론트엔드 > React' 카테고리의 다른 글
HOC (1) | 2022.06.04 |
---|---|
useCallback 과 useMemo (0) | 2022.06.04 |
Memoization (0) | 2022.06.04 |
useContext (0) | 2022.05.14 |
재조정 (Reconciliation) (0) | 2022.03.11 |