리액트에서 객체나 리스트는 항상 불변성이 유지되어야한다. (정말 싫다)
spread, map, filter, concat 등 정말정말 불편하다.
이를 쉽게 해주는 Immer 라이브러리가 존재한다.
설치
$yarn add immer
//보통 produce로 사용한다.
import produce from 'immer';
사용
const myObject = {
index : 1,
name : 'park'
};
//produce 함수를 사용하면 간단히 불변성 유지를 하며 요소의 변경이 가능하다.
const nextState = produce(myObject, draft => {
draft.index += 1;
});
useState와 함께 사용
const onClick = useCallback(() => {
//useCallback을 사용하므로 함수형 useState를 사용한다.
setTodo(
produce(draft => {
draft.done = !draft.done;
})
);
}, []);
state 매개변수를 생략하게 되면 상태를 반환하는 것이 아니라 함수 자체를 반환해준다.
따라서, 위의 코드에서는 useState를 함수형으로 사용했기에 함수형 immer를 사용한 것이다.
조금 풀어서 적으면 다음과 같이 이해할 수 있다.
setTodo(
todo => {immer(todo);}
);
immer(state) => produce(state, draft) => {
draft.done = !draft.done;
}
다시 말해 useState 함수형에는 상태가 return 값이 되는 것이 아니라, 상태가 변화되는 연산을 담은 함수가 위치하므로
immer가 이와 같은 방식으로 정의될 수 있는 것이다.
다만, immer는 전통 방식에 비해 속도가 몇 배정도 느리기때문에, 불변성 유지하는 코드 작성이 까다로운 경우만 사용해야한다.
(사실 성능이 중요한 웹에서 속도가 느리다는 뜻은 쓰지마라는 말과 똑같다. 이런게 있구나 정도로만 이해하고 넘어가자)
'React > React Basic' 카테고리의 다른 글
[React] 파일 경로를 깔끔하게 정리하기 (3) | 2022.08.29 |
---|---|
[React] useContext 및 Context API (0) | 2021.08.08 |
[리액트] useReducer 이해하기 (0) | 2021.08.07 |
[React] 불필요한 렌더링 최적화하기 (2) | 2021.08.01 |
[React] useMemo와 useCallback (0) | 2021.08.01 |