What is the difference between useEffect and useLayoutEffect?
useEffect runs after the browser has painted. useLayoutEffect runs after DOM changes but before paint, and blocks painting. Use the layout version only to measure or adjust the DOM so users do not see a flicker.
Explain it simply
Picture a wedding hall. useEffect is the decorator who comes in after the guests have already entered. useLayoutEffect is the one who finishes before the doors open, so nobody sees half-hung curtains.
Both run after React has updated the DOM. The difference is timing against the browser's paint. useEffect is deferred until after paint, so the user may see one frame with the old layout. useLayoutEffect runs synchronously first, and any state update inside it triggers a re-render before the screen is drawn.
Because it blocks painting, a slow layout effect makes the screen feel stuck. Prefer useEffect and switch only when you actually see a visible jump, such as a tooltip appearing in the wrong position for one frame.
Example
function Tooltip({ text }) {
const ref = useRef(null);
const [top, setTop] = useState(0);
useLayoutEffect(() => {
setTop(ref.current.getBoundingClientRect().height); // measure before paint
}, [text]);
return <div ref={ref} style={{ marginTop: -top }}>{text}</div>;
}It does not run on the server, so server-rendered pages may log a warning.
What to say in the interview
"Both run after render commits to the DOM, but useLayoutEffect fires synchronously before the browser paints, while useEffect fires after paint. I use useLayoutEffect for measuring and positioning, where a flash would be visible, and useEffect for everything else."
Common mistakes
- Using useLayoutEffect for data fetching, which delays the first paint for no reason.