Immer 라이브러리로 상태 불변성 관리하기
리액트에서 불변성 지키면서 상태 관리하기
리액트에서는 상태를 불변성으로 관리해야 한다.
보통 상태를 업데이트 할 때 스프레드 연산자를 사용하여 얕은 복사를 한다.
1
2
3
4
5
6
7
const onToggle = (id) => {
setUsers(
users.map((user) =>
user.id === id ? { ...user, active: !user.active } : user
)
)
}
하지만 객체 구조가 복잡하여 깊은 복사를 해야하는 경우 불편함이 있다.
Immer 사용하기
1
yarn add immer
Immer는 리액트에서 불변성을 유지하는 코드를 작성하기 쉽게 해주는 라이브러리이다.
Immer에서 제공하는 produce 함수를 사용하면 object 타입의 상태를 편리하게 업데이트 할 수 있다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
import React, { useCallback, useState } from 'react'
import produce from 'immer'
const TodoList = () => {
const [todos, setTodos] = useState([
{
id: 'React',
title: 'Learn React',
done: true
},
{
id: 'Immer',
title: 'Try Immer',
done: false
}
])
const handleToggle = useCallback((id) => {
setTodos(
produce((draft) => {
const todo = draft.find((todo) => todo.id === id)
todo.done = !todo.done
})
)
}, [])
const handleAdd = useCallback(() => {
setTodos(
produce((draft) => {
draft.push({
id: 'todo_' + Math.random(),
title: 'A new todo',
done: false
})
})
)
}, [])
}
useImmer를 사용하면 상태를 업데이트할 때 produce를 자동으로 래핑할 수도 있다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
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
});
});
}, []);
참고사이트
This post is licensed under CC BY 4.0 by the author.