Как можно не допустить batching?
Продвинутые темы
Батчинг в React отключают через `flushSync` (из react-dom) — он заставляет применить обновление состояния немедленно, вызвав синхронный ре-рендер.
Что такое батчинг
React объединяет несколько обновлений состояния в один ре-рендер (для производительности):
setCount(c => c + 1);
setFlag(true);
// один ре-рендер, а не дваС React 18 батчинг работает везде (события, промисы, setTimeout).
Как отключить — flushSync
flushSync применяет обновление синхронно, вне батчинга — компонент перерисовывается немедленно:
import { flushSync } from 'react-dom';
flushSync(() => {
setCount(c => c + 1);
});
// здесь DOM уже обновлён — ре-рендер произошёл синхронно
flushSync(() => {
setFlag(true);
});
// ещё один синхронный ре-рендерКаждый flushSync вызывает отдельный синхронный ре-рендер.
Когда нужно (редко)
- Нужно прочитать DOM сразу после обновления (измерить размеры после изменения).
- Интеграция со сторонним кодом, ожидающим синхронного обновления.
- Управление фокусом/скроллом после изменения.
flushSync(() => setItems(newItems));
listRef.current.scrollTop = listRef.current.scrollHeight; // DOM уже обновлёнНюансы
- Не злоупотреблять — flushSync убивает оптимизацию батчинга (лишние ре-рендеры, хуже производительность).
- Нужен редко — обычно батчинг желателен.
Коротко для собеседования
Батчинг отключают через flushSync(() => setState(...)) из react-dom — он применяет обновление синхронно, вызывая немедленный ре-рендер (DOM обновлён сразу после). Нужен редко: прочитать DOM после обновления (измерения, скролл, фокус), интеграция со сторонним кодом. Злоупотребление вредит производительности — обычно батчинг желателен.