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 группирует обновления асинхронно, и диалог печати отображается до обновления состояния.