PassFront
  1. PassFront
  2. База знаний
  3. Рендеринг и производительность

Зачем React ожидает выполнения всех действий пользователя для рендера?

Рендеринг и производительность

Речь о батчинге (группировке) обновлений: React намеренно не рендерит после каждого setState, а накапливает обновления и выполняет один рендер на всю пачку.

Что происходит

const handleClick = () => {
  setCount((c) => c + 1);   // рендера ещё нет
  setFlag(true);            // и ещё нет
  setUser(newUser);         // и теперь — ОДИН рендер на все три
};

Если бы каждый setState рендерил немедленно: три рендера, три диффа, три возможных правки DOM — и промежуточные состояния (count обновился, flag ещё нет) мелькали бы на экране.

Зачем это нужно

  • Производительность: один цикл рендер→дифф→коммит вместо N; меньше reflow.
  • Консистентность: пользователь не видит «полуобновлённых» состояний — UI переходит из старого состояния сразу в новое целиком.
  • Обработчик события завершится полностью до рендера — все связанные обновления гарантированно попадают в один кадр.

Эволюция: React 17 → 18

  • До React 18 батчинг работал только в React-обработчиках событий; в setTimeout/промисах/нативных слушателях каждый setState рендерил отдельно.
  • React 18 (createRoot) — автоматический батчинг везде: таймеры, промисы, fetch-колбэки.
// React 18: один рендер даже здесь
setTimeout(() => {
  setA(1);
  setB(2);
}, 100);
  • Нужен синхронный рендер немедленно (редко — измерения DOM) — flushSync(() => setX(...)) из react-dom.

Следствие для кода

setState «не срабатывает сразу»: значение в текущем замыкании не меняется; читать «обновлённый» state сразу после сеттера нельзя — реагировать на изменения нужно эффектами или вычислением при следующем рендере.

Коротко для собеседования

Это батчинг: React собирает все setState синхронного блока (обработчика, а с React 18 — любого контекста) и делает один рендер — ради производительности (один дифф/коммит) и консистентности UI без промежуточных состояний. Форсировать немедленный рендер можно flushSync, но это исключение.

Другие вопросы раздела