[React] Force React to update it's DOM by using flushSync
Refer to https://react.dev/reference/react-dom/flushSync
For example, the browser onbeforeprint
API allows you to change the page immediately before the print dialog opens. This is useful for applying custom print styles that allow the document to display better for printing. In the example below, you use flushSync
inside of the onbeforeprint
callback to immediately “flush” the React state to the DOM. Then, by the time the print dialog opens, isPrinting
displays “yes”:
Without flushSync
, the print dialog will display isPrinting
as “no”. This is because React batches the updates asynchronously and the print dialog is displayed before the state is updated.
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>
</>
);
}