Pitfall

Использование flushSync встречается редко и может ухудшить производительность вашего приложения.

flushSync позволяет принудительно заставить React выполнить любые обновления внутри переданного колбэка синхронно. Это гарантирует, что DOM обновится немедленно.

flushSync(callback)

Справочник

flushSync(callback)

Вызовите flushSync, чтобы React сразу применил все обновления и отобразил изменения в DOM без задержки.

import { flushSync } from 'react-dom';

flushSync(() => {
setSomething(123);
});

В большинстве случаев flushSync можно избежать. Используйте flushSync только в крайнем случае.

См. больше примеров ниже.

Параметры

  • callback: Функция. React немедленно вызовет этот колбэк и синхронно выполнит все обновления, которые он содержит. Также могут быть выполнены ожидающие обновления, эффекты или обновления внутри эффектов. Если обновление при вызове flushSync приостановится, могут быть заново показаны запасные состояния.

Возвращаемое значение

flushSync возвращает undefined.

Предостережения

  • flushSync может значительно ухудшить производительность. Используйте его с осторожностью.
  • flushSync может заставить ожидающие границы Suspense показать состояние fallback.
  • flushSync может выполнить ожидающие эффекты и синхронно применить любые обновления, которые они содержат, до возвращения.
  • flushSync может выполнить обновления за пределами колбэка, если это необходимо для выполнения обновлений внутри колбэка. Например, если есть ожидающие обновления от клика, React может выполнить их до выполнения обновлений внутри колбэка.

Использование

Синхронное выполнение обновлений для интеграции с третьими сторонами

При интеграции с кодом третьих сторон, таким как API браузера или UI-библиотеки, может потребоваться заставить React синхронно выполнить обновления. Используйте flushSync, чтобы синхронно выполнить любые обновления состояния внутри колбэка:

flushSync(() => {
setSomething(123);
});
// К этому моменту DOM уже обновлён.

Это гарантирует, что к моменту выполнения следующей строки кода React уже обновил DOM.

Использование flushSync встречается редко, и частое его применение может значительно ухудшить производительность вашего приложения. Если ваше приложение использует только API React и не интегрируется с библиотеками третьих сторон, то flushSync не нужен.

Однако он может быть полезен при интеграции с кодом третьих сторон, например с API браузера.

Некоторые API браузера ожидают, что результаты внутри колбэков будут записаны в DOM синхронно, к концу колбэка, чтобы браузер мог что-то сделать с отрисованным DOM. В большинстве случаев React автоматически обрабатывает это за вас. Но иногда может потребоваться принудительное синхронное обновление.

Например, API браузера onbeforeprint позволяет изменить страницу сразу перед открытием диалога печати. Это полезно для применения кастомных стилей печати, которые позволяют документу лучше отображаться при печати. В примере ниже используется flushSync внутри колбэка onbeforeprint, чтобы немедленно “сбросить” состояние React в DOM. Тогда к моменту открытия диалога печати Готово к печати: отображает “да”:

import { useState, useEffect } from 'react';
import { flushSync } from 'react-dom';

export default function PrintApp() {
  const [isPrinting, setIsPrinting] = useState(false);

  useEffect(() => {
    function handleBeforePrint() {
      flushSync(() => {
        setIsPrinting(true);
      })
    }

    function handleAfterPrint() {
      setIsPrinting(false);
    }

    window.addEventListener('beforeprint', handleBeforePrint);
    window.addEventListener('afterprint', handleAfterPrint);
    return () => {
      window.removeEventListener('beforeprint', handleBeforePrint);
      window.removeEventListener('afterprint', handleAfterPrint);
    }
  }, []);

  return (
    <>
      <h1>Готово к печати: {isPrinting ? 'да' : 'нет'}</h1>
      <button onClick={() => window.print()}>
        Печать
      </button>
    </>
  );
}

Без flushSync диалог печати будет показывать isPrinting как “no”. Это происходит потому, что React группирует обновления асинхронно, и диалог печати отображается до обновления состояния.

Pitfall

flushSync может значительно ухудшить производительность и неожиданно заставить ожидающие границы Suspense показать запасное состояние.

В большинстве случаев flushSync можно избежать, поэтому используйте его только в крайнем случае.