flushSync
flushSync
は、渡されたコールバック関数内のあらゆる更新作業を強制的かつ同期的にフラッシュ (flush) するように React に指示します。これにより、DOM が直ちに更新されることが保証されます。
flushSync(callback)
リファレンス
flushSync(callback)
flushSync
を呼び出して、保留中の作業をフラッシュし、DOM を同期的に更新するよう React に強制します。
import { flushSync } from 'react-dom';
flushSync(() => {
setSomething(123);
});
ほとんどの場合、flushSync
の使用は避けることができます。flushSync
は最後の手段として使用してください。
引数
callback
: 関数。React はこのコールバックを直ちに呼び出し、そこに含まれるすべての更新作業を同期的にフラッシュします。また、保留中の更新、エフェクト、エフェクト内の更新もフラッシュすることがあります。このflushSync
呼び出しの結果として更新のサスペンドが起きると、フォールバックが再表示される可能性があります。
返り値
flushSync
は undefined
を返します。
注意点
flushSync
はパフォーマンスを大幅に低下させる可能性があります。控え目に使用してください。flushSync
は保留中のサスペンスバウンダリを強制的にfallback
状態にする可能性があります。flushSync
はリターンの前に、保留中のエフェクトを実行し、そこに含まれた任意の更新も同期的に適用する場合があります。flushSync
は、コールバック内の更新をフラッシュするために必要な場合、コールバック外の更新もフラッシュすることがあります。例えば、クリックによる保留中の更新作業がある場合、React はコールバック内の更新をフラッシュする前に先にそれらをフラッシュするかもしれません。
使用法
サードパーティコードとの統合のために更新作業をフラッシュ
ブラウザ API や UI ライブラリなどのサードパーティのコードと統合作業を行う際には、React に更新をフラッシュするように強制する必要があるかもしれません。コールバック内の任意の state 更新 を同期的にフラッシュするよう React に強制するために flushSync
を使用します。
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 の state を即座に 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 が更新を非同期的にバッチ(束ね)処理するため、state の更新処理がなされる前に印刷ダイアログが表示されるからです。