immer
immer라는 라이브러리를 이용하여 불변성을 더 쉽게 지킬 수 있다.
Ex1)
const object = {
a: 1,
b: 2
};
object.b = 3;
리액트에서 배열이나 객체를 업데이트 할 때에는 위와 같은 코드 같이 값을 직접 수정하는 경우는 불변성을 깨는 행위다.
const object ={
a: 1,
b: 2
};
const nextObject = {
...object,
b: 3
};
이와 같은 방식으로 사용해야 나중에 컴포넌트가 제대로 리렌더링이 되고 컴포넌트 최적화도 할 수 있게 된다.
💡 배열도 마찬가지로
push, splice 같은 함수나 n번째 항목을 직접 수정해서는 안된다.
spread연산자와 배열의 내장함수를 이용하는 것이 낫다.
💡하지만 항목이 계속해서 늘어나는 순간부터 위와 같은 방법들도 불변성을 일일이 관리하면서 지켜주기 힘들어진다.
그렇기에 Immer를 사용하게 되면 불변성을 해치는 코드를 작성해도 대신 불변성 유지를 해준다.
함수형 업데이트
const [todo, setTodo] = useState({
text: 'Hello',
done: false
});
const onClick = useCallback (() => {
setTodo(todo => ({
...todo,
done: !todo.done
}));
}, [/*함수형 업데이트 기존 todo를 넣어줄 필요 없다*/]);
const todo = {
text: 'Hello',
done: false
};
const updater = produce(draft => {
draft.done = !draft.done ;
});
const nextTodo = updater(todo);
console.log(nextTodo);
// {text: 'Hello', done: true}
불변성을 지키기 어려울 때 이렇게 업데이트 함수를 이용해서 useState함수를 업데이트 해주는 관리가 가능해진다.
💡 immer같은 경우 자바스크립트 엔진이 proxy라는 기능을 이용하는데, 구형 브라우저나 React native같은 환경에서는 이 기능이 지원되지 않는다.
proxy같이 작동하지만 proxy는 아닌 es5 fallback을 이용해서 하게 된다면 크게 느려진다.
결론적으로, immer라이브러리는 데이터구조가 복잡하여 불변성을 유지해야 할 때 사용하는 것을 추천하며 무조건 사용은 방지해야 한다. 어쩔 수 없을 때 immer를 사용하며 필요한 곳에 사용하는 것이 낫다.