What does useLayoutEffect do?
What useLayoutEffect() does
The useLayoutEffect() hook lets you run side effects
right after React has updated the DOM,
but before the browser "shows" those changes to the user.
In simpler terms:
useLayoutEffectruns between the "render" phase and the "paint" phase. This gives you a chance to "catch the DOM" and do something with it before the user sees the result.
Syntax
javascript
useLayoutEffect(() => {
// code that works with the DOM
return () => {
// cleanup
};
}, [dependencies]);Difference between useEffect and useLayoutEffect
| Property | useEffect | useLayoutEffect |
|---|---|---|
| When it runs | After the browser paints | Before painting |
| Does it block rendering | No | Yes (runs synchronously) |
| Can you read/measure the DOM | Yes, but already after it is shown to the user | Yes, before it is shown (more accurate measurements) |
| Typical tasks | Requests, subscriptions, logic that does not affect markup | Measuring and syncing the DOM, positioning, animations |
| How often it's used | Very often | Rarely (only when needed) |
Example: measuring a DOM element
javascript
import { useLayoutEffect, useRef, useState } from "react";
function Box() {
const boxRef = useRef(null);
const [width, setWidth] = useState(0);
useLayoutEffect(() => {
// Runs before the browser paints
const rect = boxRef.current.getBoundingClientRect();
setWidth(rect.width);
}, []);
return (
<div ref={boxRef} style={{ width: "50%" }}>
Box width: {width}px
</div>
);
}Here:
useLayoutEffectruns before the browser shows the page.- We measure the box width while the DOM is already ready, but not yet displayed.
- This prevents "flashing" that would happen if the width were computed in
useEffect.
Example: syncing scroll or positioning
javascript
function ScrollSync({ scrollTo }) {
const ref = useRef(null);
useLayoutEffect(() => {
ref.current.scrollTop = scrollTo; // exactly before painting
}, [scrollTo]);
return (
<div
ref={ref}
style={{ height: 200, overflowY: "scroll", border: "1px solid gray" }}
>
<div style={{ height: 1000 }}>Content...</div>
</div>
);
}If we used useEffect, the user might see the scroll "jump".
With useLayoutEffect, everything happens before painting, without artifacts.
Important to remember
| Rule | Explanation |
|---|---|
| Runs synchronously after DOM changes | Blocks painting until the code finishes |
| Use it only when you need to work with the DOM directly | For example, measuring sizes, positioning |
| Do not use it for network requests or async actions | It slows down page painting |
You can have both useEffect and useLayoutEffect in the same component | React itself decides the order (layout -> paint -> effect) |
Final comparison
| Hook | When it's called | What for |
|---|---|---|
useEffect | After the browser has shown the changes | Side effects that do not affect the DOM |
useLayoutEffect | Before the browser has shown the changes | Working with the DOM, measurements, syncing before painting |
Summary
| Question | Answer |
|---|---|
What does useLayoutEffect() do | Runs code right after the DOM updates, but before the browser paints the changes |
| When to use it | When you need to measure or change the DOM before it is shown to the user |
| Why be careful | It blocks painting and can hurt performance if used unnecessarily |
| Examples | Measuring sizes, scroll, animations, preventing content flashing |
Short Answer
Interview readyPremium
A concise answer to help you respond confidently on this topic during an interview.