Suggest an editImprove this articleRefine the answer for “What does "flushSync()" do?”. Your changes go to moderation before they’re published.Approval requiredContentWhat you’re changing🇺🇸EN🇺🇦UAPreviewTitle (EN)Short answer (EN)**`flushSync(callback)`** is a function from the `react-dom` package that forces React to immediately "flush" all pending state updates inside the given callback and synchronously update the DOM. **Key point:** after `flushSync()` returns, React guarantees the component has already re-rendered, the DOM is updated, and all layout effects (`useLayoutEffect`) for that update have already run.Shown above the full answer for quick recall.Answer (EN)Image## Definition > `flushSync(callback)` is a function from the `react-dom` package > that **forces React to immediately "flush" all pending state updates** inside the given callback and **synchronously update the DOM**. ```javascript import { flushSync } from 'react-dom'; flushSync(() => { setState(newValue); }); ``` After `flushSync()` returns, React guarantees that: - the component has already **re-rendered**; - the **DOM is updated**; - all **layout effects (**`useLayoutEffect`**)** for that update have already run. --- ## 1. Why it is needed at all By default, React works **asynchronously**, especially in React 18 with **Concurrent Rendering**. It can: - defer updates; - combine several `setState` calls into one render (batching); - not update the DOM immediately. Sometimes this creates situations where you **need to see the result in the DOM right away**, for example: - to measure an element (`offsetHeight`); - to smoothly kick off an animation; - to set focus; - to react synchronously to a user action. --- ## 2. Example: without `flushSync` ```javascript function Example() { const [count, setCount] = useState(0); const divRef = useRef(); const handleClick = () => { setCount(c => c + 1); console.log(divRef.current.textContent); // old value }; return <div ref={divRef}>{count}</div>; } ``` What happens: - `setCount` puts the update in the queue; - React *schedules* a render but does not run it instantly; - the log runs **before the DOM update** -> you see the old value. --- ## 3. Example with `flushSync` ```javascript import { flushSync } from 'react-dom'; function Example() { const [count, setCount] = useState(0); const divRef = useRef(); const handleClick = () => { flushSync(() => { setCount(c => c + 1); // state update }); console.log(divRef.current.textContent); // already the new value }; return <div ref={divRef}>{count}</div>; } ``` Now React: 1. Immediately runs `setCount()`; 2. **Synchronously runs render and commit**; 3. Updates the DOM; 4. Only then returns from `flushSync`; 5. The log shows the current `count`. --- ## 4. How it works under the hood `flushSync`: - **temporarily disables concurrent batching**; - forces React to **process all pending updates** (including ones scheduled earlier); - **immediately runs the commit phase**, updating the DOM and layout effects; - then returns React to its normal asynchronous mode. ```javascript Without flushSync: setState() → wait → React decides when to update With flushSync: setState() → render right away → commit → ready DOM ``` --- ## 5. Where you need to apply this | Scenario | Why `flushSync` is needed | |---|---| | Need to measure the DOM after `setState` | To get accurate sizes | | Starting an animation right after a change | The DOM must be updated instantly | | Focusing or scrolling after an update | So the element definitely exists in the DOM | | Working with external libraries (GSAP, D3, Chart.js) | These libraries expect the current DOM state | | Sometimes - when integrating with React Transition Group, Portal, or drag-and-drop | When the commit needs to happen synchronously | --- ## 6. But use it carefully! React deliberately **makes rendering asynchronous** in order to: - avoid blocking the interface, - optimize batching of updates, - improve UI responsiveness. `flushSync()` **turns off these benefits** for a specific piece of code. ### Do not do this: ```javascript flushSync(() => { setA(1); }); flushSync(() => { setB(2); }); ``` Each call forces React to **render and commit again**, which hurts performance. It is better to group several updates into a single `flushSync()`. --- ## 7. Interaction with the lifecycle | Stage | What happens with `flushSync()` | |---|---| | Render Phase | Runs immediately for all changed components | | Commit Phase | Happens synchronously | | Effects (`useLayoutEffect`) | Run right after commit | | Effects (`useEffect`) | Still run asynchronously (on the next tick) |For the reviewerNote to the moderator (optional)Visible only to the moderator. Helps review go faster.