Запропонувати правкуПокращити цю статтюДопрацюйте відповідь до «Що таке іммутабельність стану?». Ваші зміни проходять модерацію перед публікацією.Потрібне підтвердженняКонтентЩо ви змінюєте🇺🇸EN🇺🇦UAПереглядЗаголовок (UA)Коротка відповідь (UA)**Іммутабельність (immutability)** - це принцип, при якому об'єкти або масиви не змінюються напряму, а при зміні створюється нова копія з потрібними змінами. **Ключове:** React порівнює не вміст об'єктів, а посилання - якщо посилання лишилося тим самим, React вважає, що нічого не змінилося.Показується над повною відповіддю для швидкого нагадування.Відповідь (UA)Зображення## Що таке іммутабельність стану **Іммутабельність (immutability)** - це принцип, при якому **об'єкти або масиви не змінюються напряму**, а при зміні створюється **нова копія** з потрібними змінами. > Тобто: > замість того щоб "виправити старе" -> створюємо "нове зі змінами". --- ### Приклад без іммутабельності (погано) ```javascript const [user, setUser] = useState({ name: "Alex", age: 25 }); // мутуємо об'єкт напряму user.age = 26; setUser(user); ``` Тут ти **змінив той самий об'єкт у пам'яті**, не створюючи новий. React не помітить різниці, тому що посилання на об'єкт **лишилося тим самим**. -> Ререндер не відбудеться. --- ### Приклад з іммутабельністю (правильно) ```javascript setUser(prev => ({ ...prev, age: 26 })); ``` Тепер React бачить, що `user` вказує на **новий об'єкт у пам'яті** і розуміє, що **стан змінився** -> викликає перемальовування. --- ## Чому React вимагає іммутабельного оновлення Тому що React **не порівнює вміст об'єктів** - він **порівнює посилання**. --- ### React працює за принципом **shallow compare** (поверхневе порівняння) ```javascript oldState === newState ``` Він **не заглядає всередину** об'єктів і масивів. Якщо посилання лишилося тим самим - React вирішує, що нічого не змінилося. Якщо посилання нове - React вважає, що потрібно оновити UI. --- ### Приклад: посилання і значення ```javascript const a = { x: 1 }; const b = a; // посилання на той самий об'єкт const c = { x: 1 }; // новий об'єкт з тим самим вмістом console.log(a === b); // true console.log(a === c); // false ``` React реагує на **зміну посилання (адреси)**, а не на однакові "внутрішні значення". --- ## Що ламається при мутації Якщо ти мутуєш стан напряму: 1. React **не дізнається про зміну** -> не буде ререндера. 2. **Передбачуваність порушується** - старі версії стану змінюються "по ланцюжку". 3. **Оптимізації React ламаються** (наприклад, `memo`, `PureComponent`). 4. **Відлагодження** і "time-travel" (у devtools) стають неможливими, тому що минулі стани вже зіпсовані. --- ## Приклад з масивом Погано: ```javascript setItems(items.push("новий")); // push мутує масив ``` Добре: ```javascript 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 бачить тільки **нову картину**, > тому розуміє, що потрібно оновити екран.Для рев’юераПримітка для модератора (необов’язково)Бачить лише модератор. Прискорює рев’ю.