Skip to main content

Чому setState не змінює стан миттєво?

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

setState (або setCount, setValue, тощо) не оновлює стан одразу, тому що React робить оновлення асинхронно і пакетно (batched), щоб підвищити продуктивність і уникнути зайвих перемальовок.


Що відбувається під капотом

Коли ти викликаєш:

javascript
setCount(count + 1); console.log(count); // старе значення!

Ти не бачиш нове значення, тому що React:

  1. Зберігає твій запит на оновлення (update) у внутрішню чергу.
  2. Не оновлює одразу, а планує оновлення компонента.
  3. Виконує всі накопичені зміни одним рендером, трохи пізніше (наприкінці події, ефекту, або при наступному кадрі).

Приклад

javascript
function Counter() { const [count, setCount] = useState(0); const handleClick = () => { setCount(count + 1); console.log(count); // старе значення }; useEffect(() => { console.log("Оновлено:", count); // нове значення }, [count]); return <button onClick={handleClick}>{count}</button>; }

Усередині handleClick - console.log виводить старе значення, але в useEffect (після оновлення) - вже нове.


Чому React робить саме так

1. Оптимізація продуктивності

Якби React оновлював компонент миттєво при кожному setState, а в тебе, наприклад, 10 викликів поспіль - він би 10 разів перемалював компонент.

Замість цього React групує (batching) всі оновлення:

javascript
setCount(c => c + 1); setCount(c => c + 1); setCount(c => c + 1);

-> все виконається одним рендером, а count стане +3.


2. Асинхронна природа рендерингу (Fiber)

React 18+ використовує конкурентний (concurrent) рендеринг:

  • він може призупиняти, об'єднувати і відкладати оновлення;
  • він вирішує, коли безпечно оновити UI, щоб не блокувати інтерфейс.

Тому setState - це запит на оновлення, а не негайна зміна даних.


3. Передбачуваність і чистота коду

React завжди ререндерить компонент з нуля, беручи новий стан зі своєї внутрішньої черги. Якби setState змінював значення миттєво, ти міг би випадково використати "наполовину оновлені" дані.


Підсумок

ПитанняВідповідь
Чому setState не миттєвий?Тому що React оновлює стан асинхронно і пакетно
Що робить React при setState?Кладе оновлення в чергу і планує ререндер
Коли з'явиться нове значення?При наступному ререндері компонента
Де можна побачити нове значення?У useEffect, в UI, або в callback setState

Хитрий момент

Якщо тобі потрібно оновити стан на основі попереднього, завжди використовуй функціональну форму:

javascript
setCount(prev => prev + 1);

Так React гарантує, що ти отримаєш актуальний стан, навіть якщо оновлень декілька і вони виконуються пакетно.

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

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

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