Запропонувати правкуПокращити цю статтюДопрацюйте відповідь до «Що робить middleware immer?». Ваші зміни проходять модерацію перед публікацією.Потрібне підтвердженняКонтентЩо ви змінюєте🇺🇸EN🇺🇦UAПереглядЗаголовок (UA)Коротка відповідь (UA)**`immer`** - один з найкорисніших middleware в **Zustand**, і він робить роботу зі станом простішою, безпечнішою і зручнішою, особливо якщо ти не хочеш вручну стежити за іммутабельністю. **Ключове:** `immer`-middleware дозволяє змінювати стан "як ніби напряму", але під капотом Zustand усе одно створює іммутабельну копію (тобто не мутує оригінал).Показується над повною відповіддю для швидкого нагадування.Відповідь (UA)Зображення`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 |Для рев’юераПримітка для модератора (необов’язково)Бачить лише модератор. Прискорює рев’ю.