Що таке batching в React?
Що таке batching
Batching (групування оновлень) - це механізм, за якого React об'єднує кілька викликів setState в один загальний рендер, щоб перемалювати компонент лише один раз, а не після кожної зміни стану.
Приклад без batching (у теорії)
function Counter() {
const [count, setCount] = useState(0);
const handleClick = () => {
setCount(count + 1);
setCount(count + 1);
setCount(count + 1);
};
console.log('render', count);
return <button onClick={handleClick}>{count}</button>;
}Якби batching не існував, React робив би:
setState 1 → render
setState 2 → render
setState 3 → renderЦе означало б три ререндери підряд - повільно і неефективно.
З batching (як реально працює React)
React групує всі ці оновлення в один пакет:
setState 1
setState 2
setState 3
↓
1 загальний renderТому компонент перемалюється лише один раз.
Що відбувається під капотом
React не оновлює стан негайно при виклику setState.
Він:
- Кладе оновлення в чергу (update queue);
- Чекає, поки закінчиться обробка всіх синхронних подій (наприклад,
onClick); - Після цього застосовує всі накопичені оновлення одним пакетом, переобчислює стан і викликає один рендер.
Приклад (наочний результат)
function Counter() {
const [count, setCount] = useState(0);
const handleClick = () => {
setCount(c => c + 1);
setCount(c => c + 1);
setCount(c => c + 1);
};
console.log('render');
return <button onClick={handleClick}>{count}</button>;
}Після одного кліку:
- Спрацюють усі три
setCount; countзбільшиться на 3;- Компонент перерендериться один раз.
Коли batching працює
З React 18 - завжди, за замовчуванням (раніше він працював тільки в подіях React, а тепер і в будь-яких асинхронних контекстах).
Приклад - React 17 (стара поведінка):
useEffect(() => {
setCount(c => c + 1);
setFlag(true);
});React 17: виконує два окремі рендери,
бо оновлення відбуваються асинхронно (у useEffect).
React 18: batching увімкнений навіть для async-коду (fetch, setTimeout, Promise).
Приклад (React 18 - автоматичний batching)
setTimeout(() => {
setCount(c => c + 1);
setFlag(f => !f);
}, 1000);React 17: → два рендери (batching не працював поза подіями React). React 18: → один рендер (обидві операції згруповані автоматично).
Можна вимкнути batching вручну (рідко)
Іноді потрібно негайно оновити UI (наприклад, у тестах або анімаціях).
Для цього є flushSync:
import { flushSync } from 'react-dom';
flushSync(() => setCount(c => c + 1));
flushSync(() => setFlag(true));Кожна операція виконається окремим рендером, React не буде їх групувати.
Чому batching важливий
| Перевага | Що дає |
|---|---|
| Менше ререндерів | React не оновлює компонент після кожної дрібниці |
| Більш передбачувана поведінка | Усі оновлення застосовуються "атомарно" |
| Продуктивність | Менше diffing, reconciliation і роботи з DOM |
| Консистентність | Стан переобчислюється з актуальних даних |
Як batching пов'язаний з concurrent rendering (React 18)
-
React тепер уміє "відкладати" менш важливі оновлення;
-
batching допомагає React групувати і пріоритизувати оновлення;
-
Це основа для
startTransition()іuseDeferredValue():javascriptstartTransition(() => { setSearchQuery(value); // низькопріоритетне оновлення });
Підсумок
| Що таке batching | Як працює |
|---|---|
| Механізм групування оновлень стану | Кілька setState спричиняють один рендер |
| У React 18 увімкнений скрізь | Навіть у промісах, async/await, setTimeout |
| Підвищує продуктивність | Менше непотрібних ререндерів |
Можна вимкнути через flushSync() | Для термінових оновлень |
| Основа concurrent rendering | React може оптимізувати потік рендерів |
Простими словами:
batching - це коли React чекає, поки ти "натиснеш Enter" після серії
setState, і робить один загальний рендер замість десятка дрібних.
Коротка відповідь
Для співбесідиКоротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.