Перейти к содержанию

Промежуточное ПО Immer

Промежуточное ПО Immer позволяет использовать неизменяемое состояние более удобным способом. Кроме того, с помощью Immer можно упростить работу с неизменяемыми структурами данных в Zustand.

Установка

Чтобы использовать промежуточное ПО Immer в Zustand, вам нужно установить Immer как прямую зависимость.

1
npm install immer

Использование

(Обратите внимание на дополнительные круглые скобки после параметра type, как указано в Typescript Guide).

Обновление простых состояний

 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
import { create } from 'zustand';
import { immer } from 'zustand/middleware/immer';

type State = {
    count: number;
};

type Actions = {
    increment: (qty: number) => void;
    decrement: (qty: number) => void;
};

export const useCountStore = create<State & Actions>()(
    immer((set) => ({
        count: 0,
        increment: (qty: number) =>
            set((state) => {
                state.count += qty;
            }),
        decrement: (qty: number) =>
            set((state) => {
                state.count -= qty;
            }),
    }))
);

Обновление сложных состояний

 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
39
40
41
42
43
44
45
46
47
48
49
import { create } from 'zustand';
import { immer } from 'zustand/middleware/immer';

interface Todo {
    id: string;
    title: string;
    done: boolean;
}

type State = {
    todos: Record<string, Todo>;
};

type Actions = {
    toggleTodo: (todoId: string) => void;
};

export const useTodoStore = create<State & Actions>()(
    immer((set) => ({
        todos: {
            '82471c5f-4207-4b1d-abcb-b98547e01a3e': {
                id: '82471c5f-4207-4b1d-abcb-b98547e01a3e',
                title: 'Learn Zustand',
                done: false,
            },
            '354ee16c-bfdd-44d3-afa9-e93679bda367': {
                id: '354ee16c-bfdd-44d3-afa9-e93679bda367',
                title: 'Learn Jotai',
                done: false,
            },
            '771c85c5-46ea-4a11-8fed-36cc2c7be344': {
                id: '771c85c5-46ea-4a11-8fed-36cc2c7be344',
                title: 'Learn Valtio',
                done: false,
            },
            '363a4bac-083f-47f7-a0a2-aeeee153a99c': {
                id: '363a4bac-083f-47f7-a0a2-aeeee153a99c',
                title: 'Learn Signals',
                done: false,
            },
        },
        toggleTodo: (todoId: string) =>
            set((state) => {
                state.todos[todoId].done = !state.todos[
                    todoId
                ].done;
            }),
    }))
);

Gotchas

В этом разделе вы найдете некоторые моменты, о которых следует помнить при использовании Zustand с Immer.

Мои подписки не вызываются

Если вы используете Immer, убедитесь, что вы действительно следуете правилам Immer.

Например, вы должны добавить [immerable] = true, чтобы объекты классов работали. Если вы этого не сделаете, Immer все равно будет мутировать объект, но не как прокси, поэтому он также обновит текущее состояние. Zustand проверяет, действительно ли состояние изменилось, поэтому, поскольку и текущее состояние, и следующее состояние равны (если вы не сделаете это правильно), Zustand пропустит вызов подписки.

CodeSandbox Demo

Источник — https://docs.pmnd.rs/zustand/integrations/immer-middleware

Комментарии