Handle asynchronous state updates in `onBeforePrint`
masterBecause React state updates are asynchronous, you must return a Promise from onBeforePrint and resolve it only after the state update has completed. This ensures react-to-print waits for the DOM to reflect the new state before printing.
const [isPrinting, setIsPrinting] = useState(false);
const contentRef = useRef(null);
const promiseResolveRef = useRef(null);
useEffect(() => {
if (isPrinting && promiseResolveRef.current) {
promiseResolveRef.current();
}
}, [isPrinting]);
const handlePrint = useReactToPrint({
contentRef,
onBeforePrint: () => {
return new Promise((resolve) => {
promiseResolveRef.current = resolve;
setIsPrinting(true);
});
},
onAfterPrint: () => {
promiseResolveRef.current = null;
setIsPrinting(false);
}
});Note for Class components: Pass the Promise resolve function to the this.setState callback: this.setState({ isPrinting: false }, resolve)
const [isPrinting, setIsPrinting] = useState(false);
const contentRef = useRef(null);
// We store the resolve Promise being used in `onBeforePrint` here
const promiseResolveRef = useRef(null);
// We watch for the state to change here, and for the Promise resolve to be available
useEffect(() => {
if (isPrinting && promiseResolveRef.current) {
// Resolves the Promise, letting `react-to-print` know that the DOM updates are completed
promiseResolveRef.current();
}
}, [isPrinting]);
const handlePrint = useReactToPrint({
contentRef,
onBeforePrint: () => {
return new Promise((resolve) => {
promiseResolveRef.current = resolve;
setIsPrinting(true);
});
},
onAfterPrint: () => {
// Reset the Promise resolve so we can print again
promiseResolveRef.current = null;
setIsPrinting(false);
}
});