logo
Back to blogs

Understanding React's flushSync API

Mar 10, 2023 - 9 min read

Understanding React's flushSync API

Understanding React's flushSync: Ensuring Synchronous Updates

React's automatic batching of state updates is a powerful feature that optimizes performance by reducing the number of re-renders. However, there are scenarios where you need to ensure that state updates and DOM changes happen immediately. This is where flushSync comes into play.

what is flushSync?

flushSync is a function provided by React that forces the processing of state updates and DOM updates synchronously. This means that any state updates wrapped inside flushSync will be applied immediately, and the DOM will be updated right away.

Why to use flushSync?

In most cases, React's automatic batching is beneficial and should be left as is. However there are specific scenarios where immediate updates are necessary, such as:

  • Focus management: Ensuring an element is in the DOM before focusing on it.
  • DOM Calculating: Calculating the size or position of an element after it has been rendered.

Example :Focus Management

Consider a scenario where you need to show an input field and immediately focus it when a button is clicked. Without flushSync, the input field might not be in the DOM where the focus is called

FocusExample.tsx
1import React, { useState, useRef } from "react"; 2import { flushSync } from "react-dom"; 3 4function FocusExample() { 5 const [show, setShow] = useState(false); 6 const inputRef = useRef(null); 7 const handleClick = () => { 8 flushSync(() => { 9 setShow(true); 10 }); 11 inputRef.current?.focus(); 12 }; 13 return ( 14 <div> 15 <button onClick={handleClick}>Show</button> 16 {show && <input ref={inputRef} />} 17 </div> 18 ); 19}

In this example , flushSync ensures that input field is rendered before the focus is called.

Example : DOM Calculating

Another common use case is calculating the size or position of an element after it has been rendered.

MeasurementExample.tsx
1import React, { useState, useRef } from "react"; 2import { flushSync } from "react-dom"; 3 4function MeasurementExample() { 5 const [height, setHeight] = useState(0); 6 const divRef = useRef(null); 7 8 const updateAndMeasure = () => { 9 flushSync(() => { 10 setHeight(100); 11 }); 12 console.log(divRef.current.getBoundingClientRect().height); 13 }; 14 15 return ( 16 <div> 17 <button onClick={updateAndMeasure}>Update and Measure</button> 18 <div ref={divRef} style={{ height }} /> 19 </div> 20 ); 21}

Here ,flushSync ensures that the height of the div is calculated after the state update has been applied.