リファレンス

flushSync(callback)

flushSyncを呼び出すと、Reactは保留中の作業を強制的に実行し、DOMを同期的に更新します。

import { flushSync } from 'react-dom';

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

ほとんどの場合、flushSyncは避けることができます。 flushSyncは最後の手段として使用してください。

以下の例を参照してください。

パラメータ

  • callback: 関数。 Reactはこのコールバックをすぐに呼び出し、含まれている更新を同期的に強制します。 また、保留中の更新、副作用、または副作用内の更新も強制する可能性があります。 このflushSync呼び出しの結果、更新がサスペンドされた場合、フォールバックが再表示される可能性があります。

戻り値

flushSyncundefinedを返します。

注意事項

  • 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`は最後の手段として使用してください。