직접적으로 보이는 코드에서 Immer를 import하거나 사용하는 부분이 보이지 않더라도 프로젝트가 Redux Toolkit을 사용하고 있다면 Redux Toolkit은 내부적으로 Immer를 사용한다.
immer는 JavaScript에서 불변성(immutability)을 관리하기 쉽게 해주는 라이브러리다. 특히, 상태 관리 라이브러리에서 불변성을 유지하는 것이 중요한데, immer는 이를 간단하고 효율적으로 처리할 수 있게 도와준다.
불변성은 데이터를 직접 변경하지 않고, 변경하려는 데이터를 복사하여 새로 만든 뒤 수정하는 방식을 의미한다.
Redux에서는 상태(state)가 불변(immutable)해야 한다. 왜냐하면 Redux는 상태 변경을 감지하기 위해 참조(reference) 비교를 사용하기 때문이다.
만약에 상태를 직접 수정할 경우
즉, 상태를 직접 수정하는 대신 기존 상태를 복사하고 변경된 새 상태를 반환해야 한다는 것이다.
JavaScript에서는 객체와 배열이 참조 타입(reference type)이기 때문에, 불변성을 유지하려면 보통 객체나 배열을 복사한 뒤 수정해야 한다. 변경된 경로만 새로운 객체가 되고, 변경되지 않은 부분은 기존 객체의 참조를 유지해서 불필요한 메모리 사용을 줄이려고 하기 때문이다.
const state = { count: 0 };
// 불변성을 유지하기 위해 새로운 객체를 생성
const newState = { ...state, count: state.count + 1 };
console.log(newState); // { count: 1 }
console.log(state); // { count: 0 } (원본은 변경되지 않음)
하지만 문제는, 복잡한 중첩 구조의 객체를 다룰 때 불변성을 유지하는 코드가 번잡하고 실수가 많아질 수 있다.😫
const state = {
user: {
profile: {
name: "John",
age: 30
}
}
};
const newState = {
...state,
user: {
...state.user,
profile: {
...state.user.profile,
age: 31
}
}
};
깊은 중첩 구조도 쉽게 업데이트 가능해진다.
const state = {
user: {
profile: {
name: "John",
age: 30
}
}
};
const newState = produce(state, draft => {
draft.user.profile.age = 31; // 간단하게 작성
});
console.log(newState.user.profile.age); // 31
console.log(state.user.profile.age); // 30
상태를 "수정하는 것처럼" 작성하면 되므로 가독성이 높아진다.👍
immer는 복잡한 불변성 코드를 간단하고 안전하게 작성할 수 있게 해주는 도구로, 상태 관리 작업을 훨씬 쉽게 만들어준다