Frontend interview practice question

What’s the difference between useEffect and useLayoutEffect? When does it matter?

HighIntermediateReact

Interview quick answer

Explain the timing guarantees of useEffect and useLayoutEffect, why useLayoutEffect blocks repainting, and when layout work needs a pre-paint guarantee. Passive effects generally run after paint for non-interaction updates, but interaction-caused effects may run before paint.

Interview focus

This React interview question tests whether you can explain useEffect vs useLayoutEffect: what is the difference, connect it to production trade-offs, and handle common follow-up questions.

  • useEffect vs useLayoutEffect: what is the difference explanation without falling back to memorized definitions
  • Hooks and Effects reasoning, edge cases, and production failure modes
  • How you would answer the most likely React interview follow-up
Practice more React interview questions
Interview answer drill

Use this React interview question to rehearse a quick answer, common mistake, follow-up, and production pitfall.

Full interview answer

Short answer

Passive useEffect callbacks generally run after paint for non-interaction updates, but React may run an interaction-caused effect before paint. Unlike useLayoutEffect, useEffect does not provide a pre-paint guarantee. useLayoutEffect runs after DOM mutations and blocks repainting until its setup and synchronous state updates finish, which matters for layout measurement and visible corrections.

The render pipeline (mental model)
<br>For a typical non-interaction update, a useful model is:

1) Render (compute the next tree)
2) Commit (apply DOM changes)
3) useLayoutEffect runs and completes before repaint
4) Browser may paint the screen
5) useEffect generally runs afterward

This is not an absolute useEffect timeline: React may run an effect caused by an interaction before paint. The stable distinction is that useEffect offers no pre-paint guarantee, while useLayoutEffect does.

Hook

When it runs

Does it block paint?

useLayoutEffect

After DOM updates, before paint

✅ Yes (blocks paint)

useEffect

Generally after paint for non-interaction updates; may run before paint for interactions

No layout-style pre-paint guarantee

The critical timing difference

Why this difference exists

useLayoutEffect exists for code that must synchronously read or modify layout before repaint. useEffect is the default for synchronization that does not require that guarantee, such as subscriptions, logging, timers, or network coordination. Its exact position relative to paint can vary with the cause of the update.

JSX
function Example() {
  const ref = useRef(null);

  useLayoutEffect(() => {
    const rect = ref.current.getBoundingClientRect();
    // Measure and synchronously adjust layout
  }, []);

  return <div ref={ref}>Hello</div>;
}
                  

What happens if you use useEffect for layout work?

Because useEffect provides no pre-paint guarantee, the browser may paint the initial layout before the effect measures and corrects it. A later state update can then cause another paint, producing a visible flicker or jump. Use useLayoutEffect only when that pre-paint correction is required.

JSX
function Tooltip({ text }) {
  const ref = useRef(null);
  const [top, setTop] = useState(0);

  // ❌ This can cause visible jump
  useEffect(() => {
    const rect = ref.current.getBoundingClientRect();
    setTop(rect.top - 10);
  }, []);

  return (
    <div ref={ref} style={{ position: 'absolute', top }}>
      {text}
    </div>
  );
}
                  

Correct version:

JSX
useLayoutEffect(() => {
  const rect = ref.current.getBoundingClientRect();
  setTop(rect.top - 10);
}, []);
// ✅ User never sees the wrong position
                  

When you should use useLayoutEffect

Scenario

Why

Examples

Measuring DOM size/position

Must read layout before paint

getBoundingClientRect, offsetWidth

Synchronously adjusting layout

Prevent visible jumps

Tooltips, popovers, modals

Scroll position corrections

Avoid one-frame wrong scroll

Scroll restoration, anchored lists

Imperative animations setup

Need correct initial layout

FLIP animations, measurement-based motion

Legitimate use cases for useLayoutEffect

When you should use useEffect (almost always)

• Data fetching
• Subscriptions / event listeners
• Logging / analytics
• Timers
• Syncing with external systems

These usually do not require a pre-paint layout guarantee. Their scheduling relative to paint can still vary, especially when an interaction causes the update.

Why you should avoid overusing useLayoutEffect

Because it blocks the browser from painting. Too many or heavy useLayoutEffect calls = slow first paint and janky UI.

SSR warning

useLayoutEffect does nothing on the server and causes warnings in SSR environments. Many frameworks alias it to useEffect on the server. Another reason to only use it when truly necessary.

Rule of thumb

Start with useEffect. Only switch to useLayoutEffect if you see a visual flicker, layout jump, or need to measure/mutate layout before paint.

Interview framing

Say it like this:
"Passive effects generally run after paint for non-interaction updates, but React may run an interaction-caused effect before paint. Unlike useLayoutEffect, useEffect does not provide a pre-paint guarantee. useLayoutEffect blocks repainting, so reserve it for layout measurement or corrections that must be invisible to the user."

Summary

useLayoutEffect runs after DOM mutations and blocks repainting, making it suitable for layout work that needs a pre-paint guarantee. useEffect is preferred for most external synchronization, but it is not accurate to promise that it always runs after paint. Overusing useLayoutEffect hurts performance, so use it only when visual correctness requires that guarantee.

Guides
Preparing for interviews?