Запропонувати правкуПокращити цю статтюДопрацюйте відповідь до «Зміна стану напряму». Ваші зміни проходять модерацію перед публікацією.Потрібне підтвердженняКонтентЩо ви змінюєте🇺🇸EN🇺🇦UAПереглядЗаголовок (UA)Коротка відповідь (UA)Не можна змінювати стан напряму, тому що **React не дізнається**, що ти його змінив. А отже - **не відбудеться перемальовування (re-render)**. **Ключове:** React дізнається про зміну лише через `setState()`, тому пряма мутація ламає і оновлення UI, і порівняння старого та нового стану.Показується над повною відповіддю для швидкого нагадування.Відповідь (UA)Зображення## Коротка відповідь Не можна змінювати стан напряму, тому що **React не дізнається**, що ти його змінив. А отже - **не відбудеться перемальовування (re-render)**. --- ## Приклад Неправильно: ```javascript function Counter() { const [count, setCount] = useState(0); function increment() { count = count + 1; // напряму змінюємо значення } return <button onClick={increment}>{count}</button>; } ``` Правильно: ```javascript function Counter() { const [count, setCount] = useState(0); function increment() { setCount(count + 1); // використовуємо setCount } return <button onClick={increment}>{count}</button>; } ``` У першому випадку React **не перемалює компонент**, у другому - **так**, бо React тепер знає, що потрібно оновити UI. --- ## Чому так відбувається ### 1. React **не стежить за змінними напряму** React не використовує "реактивність" як, наприклад, Vue чи Svelte. Він не «підписаний» на змінні і не відстежує їхні зміни. `useState` створює внутрішній запис стану в React (у дереві Fiber). Коли ти викликаєш `setState`, React: - зберігає нове значення у внутрішній структурі, - позначає компонент як «такий, що потребує оновлення», - викликає **перерендер**. Якщо ти просто зробиш `count++`, React **не дізнається** про цю зміну - бо ти змінив лише **локальну змінну**, а не те, що React зберігає всередині себе. --- ### 2. Пряма мутація ламає **іммутабельність** React очікує, що стан - **незмінний** (immutable). Коли ти змінюєш його напряму, React не може порівняти «було / стало». Приклад з об'єктом: Погано: ```javascript setUser(user.name = "Timur"); ``` Добре: ```javascript setUser({ ...user, name: "Timur" }); ``` Чому? React під час перерендеру **порівнює старий об'єкт і новий** (через поверхневе порівняння). Якщо посилання змінилося - значить, дані нові → потрібно оновити UI. Якщо посилання те саме - React вирішить, що нічого не змінилося. --- ### 3. Пряма мутація ламає передбачуваність React оптимізує оновлення, може їх **групувати (batching)**, і якщо ти мутуєш state вручну, ці оптимізації ламаються - UI може опинитися в неконсистентному стані. --- ## Підсумок | Причина | Пояснення | |---|---| | React не стежить за змінними | Він дізнається про зміну лише через `setState()` | | Порушення іммутабельності | Пряма мутація ламає порівняння старого і нового стану | | Втрата передбачуваності | React не зможе безпечно оптимізувати оновлення | | Немає перемальовування | UI не оновиться, навіть якщо дані змінилися |Для рев’юераПримітка для модератора (необов’язково)Бачить лише модератор. Прискорює рев’ю.