Immer
- 독일어로 항상이라는 뜻
- 불변성을 유지하면서 편하게 작업할 수 있는 패키지
간단한 사용 예시
const baseState = [
{
title: "Learn TypeScript",
done: true,
},
{
title: "Try Immer",
done: false,
},
];
const nextState = baseState.slice();
nextState[1] = {
...nextState[1],
done: true,
};
nextState.push({ title: "Tweet about it" });
- Immer 패키지가 없다면 위와 같이 작업해야 함
import { produce } from "immer";
const nextState = produce(baseState, (draft) => {
draft[1].done = true;
draft.push({ title: "Tweet about it" });
});
- Immer 패키지가 있으면 위와 같이 간단하게 처리할 수 있음
설치
- Yarn: yarn add immer
- NPM: npm install immer
주의점
- Immer는 자바스크립트 엔진의 프록시 기능을 사용
- 프록시 기능을 지원하지 않는 경우, ES5의 문법을 사용하는데 속도가 느려짐
produce
import { produce } from "immer";
const baseState = [
{
title: "Learn TypeScript",
done: true,
},
{
title: "Try Immer",
done: false,
},
];
const nextState = produce(baseState, (draftState) => {
draftState.push({ title: "Tweet about it" });
draftState[1].done = true;
});
- produce(baseState, recipe: (draftState) => void): nextState
- baseState: 작업할 객체
- recipe: 객체를 작업하는 콜백 함수
- draftState: recipe의 기본 상태의 프록시
응용
import { produce } from "immer";
function toggleTodo(state, id) {
return produce(state, (draft) => {
const todo = draft.find((todo) => todo.id === id);
todo.done = !todo.done;
});
}
const baseState = [
{
id: "JavaScript",
title: "Learn TypeScript",
done: true,
},
{
id: "Immer",
title: "Try Immer",
done: false,
},
];
const nextState = toggleTodo(baseState, "Immer");
- 위와 같이 produce 함수 자체를 반환해서 간단하게 사용 가능
useImmer
import React, { useCallback } from "react";
import { useImmer } from "use-immer";
const TodoList = () => {
const [todos, setTodos] = useImmer([
{
id: "React",
title: "Learn React",
done: true
},
{
id: "Immer",
title: "Try Immer",
done: false
}
]);
const handleToggle = useCallback((id) => {
setTodos((draft) => {
const todo = draft.find((todo) => todo.id === id);
todo.done = !todo.done;
});
}, []);
const handleAdd = useCallback(() => {
setTodos((draft) => {
draft.push({
id: "todo_" + Math.random(),
title: "A new todo",
done: false
});
});
}, []);
- useState + Immer
- 리액트에서 사용할 수 있는 Hook
- useState와 사용 방법은 동일
출처