MediumEvent Loop & Batching💻 Output Question

useLayoutEffect vs useEffect timing

💡

Hint

Use useLayoutEffect only when you need to read DOM measurements and update state/DOM before the user sees anything (avoid flicker). For everything else, use useEffect.

What does this output?

const log = [];

// useLayoutEffect fires synchronously after DOM mutations but before paint
function simulateLayoutEffect(fn) {
  log.push('DOM mutation');
  fn(); // synchronous — blocking
  log.push('browser paints here');
}

// useEffect fires after paint
function simulateEffect(fn) {
  log.push('browser paints here');
  queueMicrotask(fn); // async — after paint
}

// Scenario 1: useLayoutEffect
log.push('render');
simulateLayoutEffect(() => log.push('layout effect'));

// Scenario 2: useEffect
log.push('---');
log.push('render2');
simulateEffect(() => log.push('effect'));

setTimeout(() => console.log(log.join(' | ')), 10);

Correct Output

render | DOM mutation | layout effect | browser paints here | --- | render2 | browser paints here | effect

Why this output?

Explanation: useLayoutEffect: fires synchronously after DOM update, BEFORE browser paints. useEffect: fires after paint. Layout effect can update DOM without the user seeing a flicker.

Key Insight: Use useLayoutEffect only when you need to read DOM measurements and update state/DOM before the user sees anything (avoid flicker). For everything else, use useEffect.

Practice predicting output live →

66 output questions with instant feedback

💻 Try Output Quiz