Зміна стану напряму
Коротка відповідь
Не можна змінювати стан напряму, тому що React не дізнається, що ти його змінив. А отже - не відбудеться перемальовування (re-render).
Приклад
Неправильно:
function Counter() {
const [count, setCount] = useState(0);
function increment() {
count = count + 1; // напряму змінюємо значення
}
return <button onClick={increment}>{count}</button>;
}Правильно:
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 не може порівняти «було / стало».
Приклад з об'єктом: Погано:
setUser(user.name = "Timur");Добре:
setUser({ ...user, name: "Timur" });Чому? React під час перерендеру порівнює старий об'єкт і новий (через поверхневе порівняння). Якщо посилання змінилося - значить, дані нові → потрібно оновити UI. Якщо посилання те саме - React вирішить, що нічого не змінилося.
3. Пряма мутація ламає передбачуваність
React оптимізує оновлення, може їх групувати (batching), і якщо ти мутуєш state вручну, ці оптимізації ламаються - UI може опинитися в неконсистентному стані.
Підсумок
| Причина | Пояснення |
|---|---|
| React не стежить за змінними | Він дізнається про зміну лише через setState() |
| Порушення іммутабельності | Пряма мутація ламає порівняння старого і нового стану |
| Втрата передбачуваності | React не зможе безпечно оптимізувати оновлення |
| Немає перемальовування | UI не оновиться, навіть якщо дані змінилися |
Коротка відповідь
Для співбесідиКоротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.