flushSync

陷阱

使用 flushSync 並不常見,而且可能會損害應用程式的效能。

flushSync 可讓您強制 React 同步更新提供的回呼函式內的任何更新。這可確保 DOM 立即更新。

flushSync(callback)

參考

flushSync(callback)

呼叫 flushSync 強制 React 同步更新任何待處理的工作並更新 DOM。

import { flushSync } from 'react-dom';

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

大多數情況下,可以避免使用 flushSync。 將 flushSync 作為最後手段。

請參閱下方更多範例。

參數

  • callback:一個函式。React 將立即呼叫此回呼函式並同步更新它包含的任何更新。它也可能會更新任何待處理的更新、效果或效果內的更新。如果更新因這次 flushSync 呼叫而暫停,則可能會重新顯示後備 UI。

回傳值

flushSync 回傳 undefined

注意事項

  • flushSync 會顯著降低效能。請謹慎使用。
  • flushSync 可能會強制待處理的 Suspense 邊界顯示其 fallback 狀態。
  • flushSync 可能會執行待處理的效果,並在返回之前同步套用它們包含的任何更新。
  • 如有必要,`flushSync` 會在回調函式之外刷新更新,以刷新回調函式內的更新。例如,如果點擊事件有待處理的更新,React 可能會在刷新回調函式內的更新之前先刷新這些更新。

用法

為第三方整合刷新更新

當與第三方程式碼(例如瀏覽器 API 或 UI 函式庫)整合時,可能需要強制 React 刷新更新。使用 `flushSync` 強制 React 同步刷新回調函式內的任何狀態更新

flushSync(() => {
setSomething(123);
});
// By this line, the DOM is updated.

這可確保在執行下一行程式碼時,React 已經更新了 DOM。

使用 `flushSync` 並不常見,而且經常使用它會嚴重損害應用程式的效能。如果您的應用程式僅使用 React API,並且未與第三方函式庫整合,則應該不需要 `flushSync`。

但是,它有助於與瀏覽器 API 等第三方程式碼整合。

某些瀏覽器 API 期望在回調函式結束前,將回調函式內的結果同步寫入 DOM,以便瀏覽器可以對渲染的 DOM 執行某些操作。在大多數情況下,React 會自動為您處理此問題。但在某些情況下,可能需要強制執行同步更新。

例如,瀏覽器 `onbeforeprint` API 允許您在列印對話方塊開啟之前立即更改頁面。這對於套用自訂列印樣式很有用,可讓文件在列印時顯示更佳。在以下範例中,您在 `onbeforeprint` 回調函式內使用 `flushSync` 立即將 React 狀態「刷新」到 DOM。然後,在列印對話方塊開啟時,`isPrinting` 會顯示「yes」。

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: {isPrinting ? 'yes' : 'no'}</h1>
      <button onClick={() => window.print()}>
        Print
      </button>
    </>
  );
}

如果沒有 `flushSync`,列印對話方塊會將 `isPrinting` 顯示為「no」。這是因為 React 以非同步方式批次處理更新,並且在狀態更新之前顯示列印對話方塊。

陷阱

`flushSync` 會嚴重損害效能,並且可能意外強制待處理的 Suspense 邊界顯示其後備狀態。

大多數情況下,可以避免使用 `flushSync`,因此請將 `flushSync` 作為最後手段。