Skip to main content

Що робить Immer.js всередині Redux Toolkit?

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

Immer.js всередині Redux Toolkit відповідає за іммутабельне оновлення стану. Він дозволяє тобі писати код так, ніби ти мутуєш об'єкт, але насправді створює новий, незмінний стан за допомогою Proxy.


Що відбувається при виклику createSlice()

Коли ти пишеш редьюсер у RTK на кшталт цього:

javascript
const counterSlice = createSlice({ name: 'counter', initialState: { value: 0 }, reducers: { increment(state) { state.value++ // ← ти ніби мутуєш }, }, })

RTK не зберігає цей reducer напряму. Під капотом він огортає твою функцію через Immer:

javascript
import { produce } from 'immer' function wrappedReducer(state, action) { return produce(state, draft => { state.value++ // ← стає "draft.value++" }) }

Immer бере state, створює для нього "чернетку" (draft), дозволяє в ній робити зміни, і після завершення повертає новий стан, у якому змінені лише потрібні поля, а все решта - те саме (за посиланнями).


Як працює produce() (серце Immer)

Ось мінімальна реалізація "магії":

javascript
import { produce } from 'immer' const baseState = { count: 1, user: { name: 'Maria' } } const nextState = produce(baseState, draft => { draft.count++ draft.user.name = 'Alex' }) console.log(nextState) // { count: 2, user: { name: 'Alex' } } console.log(baseState) // { count: 1, user: { name: 'Maria' } } не змінився

Що насправді робить Immer під капотом

  1. Створює Proxy для об'єкта state Кожен доступ до властивості (get, set, delete) перехоплюється.
  2. Запам'ятовує всі зміни, які ти зробив Immer не змінює об'єкт одразу - він записує інструкції:
javascript
- збільшити count - змінити user.name
  1. Після виходу з produce() Immer створює нове дерево стану, копіюючи лише змінені частини. Усе, що не змінювалося, залишається за старими посиланнями → це дуже ефективно за пам'яттю.
  2. Повертає новий state Новий об'єкт "чистий" і іммутабельний - його можна безпечно передавати далі в Redux.

Приклад: вкладені зміни

javascript
const state = { user: { name: 'Maria', age: 25 }, settings: { theme: 'dark' } } const next = produce(state, draft => { draft.user.age = 26 })

Immer:

  • Створює нову копію тільки гілки user
  • settings залишається за тим самим посиланням
  • Тому next.settings === state.settingstrue

Це робить оновлення дуже продуктивними, бо копіюється тільки змінена частина дерева.


Як RTK використовує Immer всередині

Redux Toolkit інтегрує Immer у createReducer() і createSlice().

Кожен редьюсер, який ти оголошуєш, фактично стає:

javascript
(state, action) => produce(state, draft => { // твій код })

У RTK це робиться автоматично, тобі не потрібно явно викликати produce().


Приклад без RTK (чистий Redux)

javascript
function userReducer(state = { name: 'Maria', age: 25 }, action) { switch (action.type) { case 'UPDATE_NAME': return { ...state, name: action.payload } default: return state } }

Приклад з RTK (Immer всередині)

javascript
const userSlice = createSlice({ name: 'user', initialState: { name: 'Maria', age: 25 }, reducers: { updateName(state, action) { state.name = action.payload // працює завдяки Immer } } })

Обидва роблять одне й те саме - тільки в RTK код удвічі коротший, і іммутабельність гарантована автоматично.


Чому це важливо

Проблема без ImmerЩо вирішує Immer
Потрібно вручну копіювати об'єкти ({ ...state })Робить це автоматично
Помилки мутаціїВиключає їх
Складно оновлювати вкладені структуриМожна звертатися напряму (state.user.name = ...)
Повільне глибоке копіюванняКопіює тільки змінені гілки
Багато шаблонного кодуКод стає природним і коротким

Візуально (що робить Immer)

javascript
[оригінальний стан] створюється proxy (draft) ти "мутуєш" draft Immer фіксує зміни повертає новий стан (іммутабельний)

Підсумок

Що робить Immer всередині RTKЯк це виглядає
Створює "чернетку" стану через Proxydraft
Дозволяє мутувати draftstate.value++
Відстежує всі зміничерез пастки Proxy
Після виходу створює новий stateіммутабельна копія
Копіює тільки змінені гілкиощадливо і швидко
Гарантує безпеку станубез ручних spread'ів

Підсумкове визначення:

Immer.js у Redux Toolkit - це "невидимий посередник", який перетворює твій "мутуючий" код на чисту, іммутабельну трансформацію стану з мінімальними змінами в пам'яті і максимальною безпекою.

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

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

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