useLayoutEffect vs useEffect

Timing

render → React updates DOM → useLayoutEffect → browser paints → useEffect
useEffectuseLayoutEffect
Runsafter paint (async)before paint (blocks paint)
Use fordata fetching, subscriptions, loggingmeasuring element size/position, avoiding flicker
Default choiceyesonly when you see flicker

Measure an Element

Example

The width is measured before the user sees the box, so the label never flashes a wrong value.

import { useState, useRef, useLayoutEffect } from 'react';

export default function App() {
  const boxRef = useRef(null);
  const [width, setWidth] = useState(0);
  const [text, setText] = useState('Hello');

  useLayoutEffect(() => {
    setWidth(boxRef.current.getBoundingClientRect().width);
  }, [text]);

  return (
    <div>
      <input value={text} onChange={(e) => setText(e.target.value)} />
      <div><span ref={boxRef} style={{ background: '#ffeb3b', padding: 4 }}>{text}</span></div>
      <p>Box width: {Math.round(width)}px</p>
    </div>
  );
}

Result