What is the difference between useEffect and useLayoutEffect? When does each one run relative to the browser painting the screen, and when would you need useLayoutEffect?
Show the explanation
Model answer. Both run after React has updated the DOM. The difference is timing relative to paint:
- `useEffect` runs after the browser has painted. It does not block the screen, so it is the right default for data fetching, subscriptions, logging and timers.
- `useLayoutEffect` runs synchronously after DOM changes but before the browser paints. The browser waits for it to finish.
Use useLayoutEffect when you must measure the DOM and then change it before the user sees anything; otherwise they would see a flicker: one frame in the wrong position, then a jump.
function Tooltip({ anchorRect, children }) {
const ref = useRef(null);
const [top, setTop] = useState(0);
useLayoutEffect(() => {
const h = ref.current.getBoundingClientRect().height; // measure
setTop(anchorRect.top - h - 8); // reposition before paint
}, [anchorRect]);
return <div ref={ref} style={{ position: 'fixed', top }}>{children}</div>;
}Costs: heavy work in useLayoutEffect delays the frame and makes the app feel slow. It also does nothing during server rendering (React warns), so measurement logic must run on the client. Start with useEffect, and switch only if you see flicker.
Original UniCircle question. Last reviewed 22 Oct 2026.
