Що таке іммутабельність стану?
Що таке іммутабельність стану
Іммутабельність (immutability) - це принцип, при якому об'єкти або масиви не змінюються напряму, а при зміні створюється нова копія з потрібними змінами.
Тобто: замість того щоб "виправити старе" -> створюємо "нове зі змінами".
Приклад без іммутабельності (погано)
const [user, setUser] = useState({ name: "Alex", age: 25 });
// мутуємо об'єкт напряму
user.age = 26;
setUser(user);Тут ти змінив той самий об'єкт у пам'яті, не створюючи новий. React не помітить різниці, тому що посилання на об'єкт лишилося тим самим. -> Ререндер не відбудеться.
Приклад з іммутабельністю (правильно)
setUser(prev => ({ ...prev, age: 26 }));Тепер React бачить, що user вказує на новий об'єкт у пам'яті
і розуміє, що стан змінився -> викликає перемальовування.
Чому React вимагає іммутабельного оновлення
Тому що React не порівнює вміст об'єктів - він порівнює посилання.
React працює за принципом shallow compare (поверхневе порівняння)
oldState === newStateВін не заглядає всередину об'єктів і масивів. Якщо посилання лишилося тим самим - React вирішує, що нічого не змінилося. Якщо посилання нове - React вважає, що потрібно оновити UI.
Приклад: посилання і значення
const a = { x: 1 };
const b = a; // посилання на той самий об'єкт
const c = { x: 1 }; // новий об'єкт з тим самим вмістом
console.log(a === b); // true
console.log(a === c); // falseReact реагує на зміну посилання (адреси), а не на однакові "внутрішні значення".
Що ламається при мутації
Якщо ти мутуєш стан напряму:
- React не дізнається про зміну -> не буде ререндера.
- Передбачуваність порушується - старі версії стану змінюються "по ланцюжку".
- Оптимізації React ламаються (наприклад,
memo,PureComponent). - Відлагодження і "time-travel" (у devtools) стають неможливими, тому що минулі стани вже зіпсовані.
Приклад з масивом
Погано:
setItems(items.push("новий")); // push мутує масивДобре:
setItems([...items, "новий"]); // створює новий масивТепер React побачить, що посилання на масив змінилося, і оновить компонент.
Коли це особливо важливо
Іммутабельність потрібна:
- при роботі з об'єктами і масивами (складні стани);
- у Redux, Zustand, Jotai, Recoil - усі ці бібліотеки тримаються на ній;
- при використанні мемоізації (
React.memo,useMemo,useCallback); - при оптимізації ререндерів.
Під капотом: чому це зручно React
Іммутабельність дає React можливість:
- швидко розуміти, які частини дерева змінилися (через порівняння посилань);
- ефективно виконувати reconciliation (узгодження);
- безпечно "перемотувати" стан у devtools;
- спрощувати оптимізації (
shouldComponentUpdate,React.memo,useMemoі т.д.).
Підсумок
| Питання | Відповідь |
|---|---|
| Що таке іммутабельність? | Дані не змінюються напряму, а замінюються новою копією |
| Чому React її вимагає? | React порівнює посилання, а не вміст об'єктів |
| Що буде при мутації? | React не помітить змін і не перемалює компонент |
| Як оновлювати правильно? | Створювати новий об'єкт/масив зі змінами |
| Приклад | setUser(prev => ({ ...prev, name: "Tim" })) |
Проста аналогія
Мутація - це "перемалювати стару картину поверх старою фарбою". Іммутабельність - це "зробити нову копію картини зі змінами".
React бачить тільки нову картину, тому розуміє, що потрібно оновити екран.
Коротка відповідь
Для співбесідиКоротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.