When does React run useLayoutEffect()?
When does React run useLayoutEffect()
React calls useLayoutEffect() after:
- the component has been rendered into the virtual DOM,
- the real DOM has already been updated (elements inserted/changed), but before the browser "shows" the changes to the user (before paint).
In other words:
useLayoutEffectruns right after React's DOM mutations, but before the screen "paints".
React's update cycle, step by step
Here is how React handles one render process:
| Stage | What happens | When it's called |
|---|---|---|
| 1. Render phase | React calls component functions -> builds a virtual tree of elements | before DOM changes |
| 2. Commit phase (DOM updates) | React updates the real DOM (insertions, removals, changes) | the DOM is ready here |
3. useLayoutEffect | Called right after the DOM update, but before it's shown to the user | right here |
| 4. Browser Paint | The browser visually paints the changes on the screen | after the layout effects |
5. useEffect | Runs after the changes have already been shown | for asynchronous effects |
Visual timeline:
javascript
Render → DOM updated → [useLayoutEffect()] → Paint (screen) → [useEffect()]An example to make it clear
javascript
import { useLayoutEffect, useEffect } from "react";
function Example() {
useLayoutEffect(() => {
console.log("useLayoutEffect");
});
useEffect(() => {
console.log("useEffect");
});
console.log("Render");
return <div>Example</div>;
}Console log:
javascript
Render
useLayoutEffect
useEffectThat is, React first renders the component, then calls the layout effect, and only after the page is shown does it call the regular effect.
Why this order matters
useLayoutEffect:
- Used for synchronous effects that affect the DOM (e.g. measurements, positioning, scrolling).
- Runs before paint, so the user doesn't see a "jump" in the interface.
useEffect:
- Used for asynchronous and side effects that don't affect the DOM (e.g. API requests, logging).
- Runs after paint, so it does not block UI rendering.
An example where the order matters
With useEffect (the user sees a "flash"):
javascript
function Box() {
const ref = useRef();
useEffect(() => {
ref.current.style.transform = "translateY(50px)";
}, []);
return <div ref={ref} style={{ width: 100, height: 100, background: "tomato" }} />;
}The problem:
React first renders the div -> the browser shows it -> then useEffect fires -> a "jump".
With useLayoutEffect (no flash at all):
javascript
useLayoutEffect(() => {
ref.current.style.transform = "translateY(50px)";
}, []);Now the style is applied before painting, and the user immediately sees the block in its correct position.
Important to remember
| Rule | Explanation |
|---|---|
useLayoutEffect runs synchronously | React waits for it to finish before "painting" |
| Can block rendering | Don't overuse it, especially for heavy computations |
| Use it only for DOM measurements and synchronization | Everything else goes through useEffect |
Cannot be called on the server (SSR) | React replaces useLayoutEffect with useEffect on the server (to avoid errors) |
Summary
| Question | Answer |
|---|---|
When does React run useLayoutEffect() | After the DOM update, but before the browser "paints" the screen |
| In what order | render → commit → useLayoutEffect → paint → useEffect |
| What it's for | Measuring the DOM, synchronizing positions, preventing "flashes" |
| When not to use it | For requests, logs, asynchronous effects - that's what useEffect is for |
Short Answer
Interview readyPremium
A concise answer to help you respond confidently on this topic during an interview.