Post

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
      });
    });
  }, []);

참고사이트

23. Immer 를 사용한 더 쉬운 불변성 관리
React & Immer

This post is licensed under CC BY 4.0 by the author.