Запропонувати правкуПокращити цю статтюДопрацюйте відповідь до «Що таке middleware у Zustand?». Ваші зміни проходять модерацію перед публікацією.Потрібне підтвердженняКонтентЩо ви змінюєте🇺🇸EN🇺🇦UAПереглядЗаголовок (UA)Коротка відповідь (UA)**Middleware у Zustand** - це функція-обгортка, яка розширює поведінку стора, додаючи додаткову логіку між зміною стану (`set`) і самим її застосуванням. **Ключове:** middleware у Zustand - це плагіни, що "вбудовуються" в store і додають нові можливості: збереження, логи, devtools, іммутабельність тощо.Показується над повною відповіддю для швидкого нагадування.Відповідь (UA)ЗображенняУ **Zustand** термін **middleware** (проміжне ПЗ) означає **функцію-обгортку**, яка **розширює поведінку стора**, додаючи додаткову логіку між зміною стану (`set`) і самим її застосуванням. Якщо простіше: > **Middleware у Zustand - це плагіни**, які "вбудовуються" в store і додають нові можливості: збереження, логи, devtools, іммутабельність тощо. --- ## Як це працює Коли ти створюєш store: ```javascript import { create } from 'zustand' const useStore = create((set) => ({ count: 0, inc: () => set((s) => ({ count: s.count + 1 })), })) ``` Zustand дозволяє обгорнути цей "чистий" store функцією-міддлварою, щоб змінити або доповнити його поведінку: ```javascript import { devtools } from 'zustand/middleware' const useStore = create( devtools((set) => ({ count: 0, inc: () => set((s) => ({ count: s.count + 1 })), })) ) ``` Тепер Zustand підключається до **Redux DevTools**, і ти можеш відстежувати стан у браузері. --- ## Популярні middleware у Zustand | Middleware | Призначення | |---|---| | `devtools` | інтеграція з Redux DevTools для відлагодження | | `persist` | зберігає стан у `localStorage`, `sessionStorage` або IndexedDB | | `immer` | дозволяє змінювати стан "імперативно" через `draft` (як у Redux Toolkit) | | `subscribeWithSelector` | підписка тільки на потрібні поля (глибока селективність) | | `combine` | допомагає об'єднувати декілька зрізів стану в один store | | `redux` | емулює Redux-подібну поведінку з actions і reducers | --- ## Приклади використання ### 1. `persist` Зберігає стан між перезавантаженнями сторінки: ```javascript import { create } from 'zustand' import { persist } from 'zustand/middleware' const useAuthStore = create( persist( (set) => ({ user: null, setUser: (user) => set({ user }), logout: () => set({ user: null }), }), { name: 'auth-storage' } // ключ у localStorage ) ) ``` Тепер дані автоматично зберігатимуться в `localStorage`. --- ### 2. `devtools` Додає інтеграцію з Redux DevTools: ```javascript import { create } from 'zustand' import { devtools } from 'zustand/middleware' const useCounterStore = create( devtools((set) => ({ count: 0, inc: () => set((s) => ({ count: s.count + 1 })), })) ) ``` Тепер можна відкривати DevTools і бачити всі зміни стану. --- ### 3. `immer` Дозволяє використовувати **мутабельний стиль оновлення** (через `draft`): ```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 }) }), })) ) ``` Тут можна "змінювати" масив напряму, ніби це звичайний JS-об'єкт - під капотом Zustand робить іммутабельне копіювання. --- ### 4. Комбінування middleware Можна використовувати декілька міддлвар одночасно - просто вкладай їх: ```javascript import { create } from 'zustand' import { devtools, persist } from 'zustand/middleware' const useStore = create( devtools( persist( (set) => ({ theme: 'light', toggleTheme: () => set((s) => ({ theme: s.theme === 'light' ? 'dark' : 'light' })), }), { name: 'theme-storage' } ) ) ) ``` --- ## Як middleware влаштоване всередині Middleware - це функція вищого порядку: ```javascript type Middleware = (createState: StateCreator) => StateCreator ``` Вона приймає `createState` (твою функцію, що створює store) і повертає **нову** функцію, яка обгортає або змінює поведінку `set`, `get`, `subscribe`. Приклад власного middleware: ```javascript const logger = (config) => (set, get, api) => config( (args) => { console.log('Before:', get()) set(args) console.log('After:', get()) }, get, api ) ``` --- ## Підсумок | Що робить middleware | Приклад | |---|---| | Додає нові функції в store | `persist`, `devtools`, `immer` | | Перехоплює і змінює `set()` | логування, фільтрація | | Розширює API стора | методи на кшталт `.persist.rehydrate()` | | Можна комбінувати | `devtools(persist(...))` |Для рев’юераПримітка для модератора (необов’язково)Бачить лише модератор. Прискорює рев’ю.