flushSync
允许你强制 React 在提供的回调函数内同步刷新任何更新,这将确保 DOM 立即更新。
flushSync(callback)
参考
flushSync(callback)
调用 flushSync
强制 React 刷新所有挂起的工作,并同步更新 DOM。
import { flushSync } from 'react-dom';
flushSync(() => {
setSomething(123);
});
大多数时候都不需要使用 flushSync
,请将其作为最后的手段使用。
参数
callback
:一个函数。React 会立即调用这个回调函数,并同步刷新其中包含的任何更新。它也可能会刷新任何挂起的更新、Effect 或 Effect 内部的更新。如果因为调用flushSync
而导致更新挂起(suspend),则可能会重新显示 fallback。
返回值
flushSync
返回 undefined
。
注意
flushSync
可能会严重影响性能,因此请谨慎使用。flushSync
可能会强制挂起的 Suspense 边界显示其fallback
状态。flushSync
可能会在返回之前运行挂起的 Effect,并同步应用其包含的任何更新。flushSync
可能会在必要时刷新回调函数之外的更新,以便刷新回调函数内部的更新。例如,如果有来自点击事件的挂起更新,React 可能会在刷新回调函数内部的更新之前刷新这些更新。
用法
刷新第三方集成更新
当与浏览器 API 或 UI 库等第三方代码集成时,可能需要强制 React 刷新更新。调用 flushSync
以强制 React 同步刷新在回调函数内的任何状态更新:
flushSync(() => {
setSomething(123);
});
// 这一行代码运行之后,DOM 将被更新。
这确保了在下一行代码运行时,React 已经更新了 DOM。
使用 flushSync
是不常见的行为,频繁调用可能会严重影响应用程序的性能。如果你的应用只使用 React API,并且不与第三方库集成,那么 flushSync
应该是不必要的。
然而,它对于与浏览器 API 等第三方代码集成可能会有帮助。
一些浏览器 API 希望回调函数内的结果同步写入 DOM,以便在回调函数结束时,浏览器可以对渲染的 DOM 进行操作。在大多数情况下,React 会自动处理这个问题。但在某些情况下,可能需要强制进行同步更新。
例如,浏览器的 onbeforeprint
API 允许你在打印对话框打开之前立即更改页面。这对于应用自定义打印样式,使文档在打印时能够更好地显示非常有用。在下面的示例中,你在 onbeforeprint
回调函数内调用 flushSync
来立即将 React 状态“刷新”到 DOM 中。然后,当打印对话框打开时,isPrinting
会显示为“是”:
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
会显示为“否”。这是因为 React 将异步批处理更新,而打印对话框在状态更新之前就显示出来了。