✅ Immer를 사용한 더 쉬운 불변성 관리
produce(state,draft)를 이용한다. 이것 하나만 알면 된다.
새로운 API를 쓰지 않고 . 참조 등으로 객체를 변경.
produce 사용법
// 1 아주 복잡한 상태가 있다고 가정하자
const todoState = [
{
content: 'hello',
refPlan: {
name: 'todoit',
},
refTodoList: [
{ content: 'deep hello1' },
{ content: 'deep hello2' },
{ content: 'deep hello3' },
],
},
{
content: 'hello',
refPlan: {
name: 'todoit',
},
refTodoList: [
{ content: 'deep hello1' },
{ content: 'deep hello2' },
{ content: 'deep hello3' },
],
},
];
// 2 기존에 아래와 같은 방식(.으로 참조하는 방식)은 불변성원칙을 지키지 않는 방식이지만
// produce를 감싼 내부에선 불병성을 지키도록 immer가 바꿔준다.
const nextState = produce(todoState, (draft) => {
draft[0].refPlan['name'] = 'hacked';
draft[0].refTodoList[0]['content'] = 'hacked';
draft[0].refTodoList[1]['content'] = 'hacked';
});
console.log(nextState);
console.log(todoState === nextState);
- Recoil 상태관리 + immer 결합
// atom 인터페이스 정의
interface IAtomTodo {
name: string;
finished: boolean;
}
// todo example 정의
const atomTodo = atom<IAtomTodo[]>({
key: 'atomTodo',
default: [
{ name: 'hello1', finished: true },
{ name: 'hello2', finished: true },
{ name: 'hello3', finished: true },
],
});
const LandingPage = () => {
const [todo, setTodo] = useRecoilState(atomTodo);
// setTodo를 produce함수를 이용해서 불변성을 관리한다.
const handleChangeTodo = (idx: number) => {
setTodo((prev) =>
produce(prev, (draft) => {
draft[idx] = { name: 'hacked', finished: false };
return draft;
}),
);
};
https://immerjs.github.io/immer/produce
https://react.vlpt.us/basic/23-immer.html