useLayoutEffect has the exact same signature as useEffect, except it fires synchronously after DOM mutations and before the browser paints pixels on screen. This timing prevents visual flicker when a component must measure an element's width or height and immediately adjust its position before the user sees it.
useLayoutEffect vs useEffect Execution Timelineflowchart LR
Render["1. Render JSX"] --> Commit["2. Commit DOM Changes"]
Commit --> LayoutEff["3. Run useLayoutEffect (Blocks Paint)"]
LayoutEff --> Paint["4. Browser Paints Pixels"]
Paint --> PassiveEff["5. Run useEffect (Async After Paint)"]
With useEffect, the browser paints the initial unpositioned tooltip for one frame, then jumps to the new coordinates—creating a noticeable flash. useLayoutEffect finishes measuring and updating state before step 4, so the user sees only the final position.
import { useLayoutEffect, useRef, useState } from 'react';
export function MeasuredBanner({ text }) {
const boxRef = useRef(null);
const [boxWidth, setBoxWidth] = useState(0);
useLayoutEffect(() => {
if (boxRef.current) {
setBoxWidth(Math.round(boxRef.current.getBoundingClientRect().width));
}
}, [text]);
return (
<div ref={boxRef} className="measured-banner">
<span>{text}</span>
<small> (Width: {boxWidth}px)</small>
</div>
);
}
useLayoutEffect MistakesuseLayoutEffect for Data Fetching or Subscriptions: Blocking browser paint while running unrelated logic slows down perceived responsiveness. Always default to useEffect unless you see visual layout flicker.useLayoutEffect does not run on the server and logs warnings during server-side rendering if called inside Server/SSR paths. Guard DOM measurements on the client or use useEffect when pre-paint sync is unnecessary.useLayoutEffect?Yes. Updating state inside useLayoutEffect makes React run a synchronous re-render before the browser paints, ensuring zero visual jump.
useLayoutEffect?Fast DOM measurements like getBoundingClientRect() take microseconds. Heavy loops inside useLayoutEffect freeze frame rendering, so keep the callback short and focused solely on layout geometry.
Suspense with useLayoutEffect?React delays running useLayoutEffect for suspended subtrees until their fallback resolves and the real DOM nodes mount.
Sign in to track your learning journey, earn industry-recognized certificates, and join our elite developer community.
Quick Access With
You've completed this section! Take a quick 5-question quiz to check your understanding.