리액트에서는 배열이나 객체를 업데이트할 때 직접 수정하는 것이 아닌 불변성을 지키며 업데이트 해주어야 한다.
const object = {
a: 1,
b: 2
};
// 직접 수정 X
object.b = 3;
// ...연산자 이용해 새로운 객체 생성
const nextObject = {
...object,
b : 3
};
객체 뿐만 아니라 배열도 마찬가지로 push, splice 등의 함수를 사용하거나 n번째 항목을 직접 수정하는 것이 아닌 다음과 같이 concat, filter, map 등의 함수를 사용해야 함.
const todos = [
{
id: 1,
text: '할 일 #1',
done: true
},
{
id: 2
text: '할 일 #2',
done: false
}
];
const inserted = todos.concat({
id: 3,
text: '할 일 #3',
done: false
});
const filtered = todos.filter(todo => todo.id !== 2);
const toggled = todos.map(
todo => todo.id === 2
? {
...todo,
done: !todo.done,
}
: todo
);
데이터의 구조가 까다로워지면 코드가 복잡해짐
→ immer를 사용하면 상태를 업데이트 할 때, 불변성을 유지하는 작업을 매우 간단하게 처리 가능
사용법(produce 함수)
- 첫번째 파라미터 : 수정하고 싶은 상태
- 두번째 파라미터 : 어떻게 업데이트하고 싶을지 정의하는 함수
- 만약 첫번째 파라미터를 생략하면, 반환 값은 새로운 상태가 아닌 상태를 업데이트해주는 함수가 됨
const state = {
number: 1,
dontChangeMe: 2
};
const nextState = produce(state, draft => {
draft.number += 1;
});
console.log(nextState);
// { number: 2, dontChangeMe: 2 }
const [todo, setTodo] = useState({
text: 'Hello',
done: false
});
const onClick = useCallback(() => {
setTodo(
produce(draft => {
draft.done = !draft.done;
})
);
}, []);
[정리]
- Immer 라이브러리는 컴포넌트의 상태 업데이트가 조금 까다로울 때 사용하면 좋음
- 만약 Immer를 사용하는 것이 오히려 불편하게 느껴진다면 사용하지 않아도 좋음
- 성능적으로는 Immer를 사용하지 않은 코드가 조금 더 빠름
- 어쩔 수 없을 때 필요한 곳에만 사용하는 것이 좋음
- 배열이 객체의 깊은곳에 위치하지 않는 경우 immer를 사용하는 것 보단 concat과 filter를 사용하는 것이 편함
'React' 카테고리의 다른 글
[React] Context API (0) | 2023.04.05 |
---|---|
[React] 라우팅 (0) | 2023.03.30 |
[React] 컴포넌트 스타일링 (0) | 2023.03.23 |
[React] Hooks (0) | 2023.03.23 |
[React] 컴포넌트의 라이프사이클 메서드 (0) | 2023.03.23 |