Skip to main content

Що робить middleware immer?

immer - одне з найкорисніших middleware в Zustand, і воно робить роботу зі станом простішою, безпечнішою і зручнішою, особливо якщо ти не хочеш вручну стежити за іммутабельністю.


Суть в одному реченні

immer-middleware дозволяє змінювати стан "як ніби напряму", але під капотом Zustand усе одно створює іммутабельну копію (тобто не мутує оригінал).


Без immer

У звичайному Zustand ти маєш явно повертати новий об'єкт, щоб React зрозумів, що стан змінився:

javascript
import { create } from 'zustand' const useTodoStore = create((set) => ({ todos: [], addTodo: (text) => set((state) => ({ todos: [...state.todos, { text, done: false }], })), }))

Тут важливо не мутувати state.todos, інакше React не побачить змін. Тобто не можна робити state.todos.push(...).


З immer

З immer ти можеш писати код у мутабельному стилі, а бібліотека під капотом створить іммутабельну копію:

javascript
import { create } from 'zustand' import { immer } from 'zustand/middleware/immer' const useTodoStore = create( immer((set) => ({ todos: [], addTodo: (text) => set((state) => { state.todos.push({ text, done: false }) // можна мутувати! }), toggleTodo: (index) => set((state) => { state.todos[index].done = !state.todos[index].done }), })) )

Тепер Zustand автоматично:

  • створює "чернетку" стану (draft);
  • застосовує до неї твої зміни;
  • створює нову версію стану без мутацій.

Як це працює під капотом

immer використовує бібліотеку Immer, яка реалізує концепцію immutable state через Proxy.

Приблизно так:

  1. Zustand створює проксі-об'єкт (draft) стану;
  2. Ти "мутуєш" його як звичайний об'єкт;
  3. Immer фіксує зміни і створює нову іммутабельну копію стану.

Переваги

ПеревагаОпис
Чистий кодПишеш у природному стилі без копіювання масивів і об'єктів
БезпекаГарантує іммутабельність (оригінал не мутується)
ПростотаНе потрібно вручну використовувати спреди (...)
СумісністьПрацює з persist, devtools та іншими middleware

Важливо пам'ятати

  • Immer трохи повільніший за "чисті" іммутабельні оновлення, якщо оновлення дуже часті (наприклад, 60 разів на секунду в анімації). Але у звичайних застосунках різниця непомітна.
  • Immer не можна використовувати разом із прямими мутаціями поза set() - він працює лише всередині функції set((state) => { ... }).

Підсумок

ПараметрБез immerЗ immer
Оновлення масивуset({ todos: [...state.todos, newTodo] })set((s) => { s.todos.push(newTodo) })
Іммутабельністьвручнуавтоматично
Кодгроміздкийлаконічний
Безпеказалежить від розробникагарантується Immer

Коротка відповідь

Для співбесіди
Premium

Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.