useLayoutEffect
React · Reference cheat sheet
useLayoutEffect
React · Reference cheat sheet
📋 Overview
useLayoutEffect runs synchronously after DOM mutations but before the browser paints. Use for measuring layout (getBoundingClientRect) and applying DOM corrections that must not flicker. Prefer useEffect for most subscriptions and data loading.
🔧 Core concepts
- Timing — render → DOM update → layout effects → paint → passive effects.
- Same API —
useLayoutEffect(setup, deps)likeuseEffect. - SSR — warns on server; gate with
typeof windowor useuseEffect. - Blocking — long work delays paint—keep short.
💡 Examples
import { useLayoutEffect, useRef, useState } from "react";
export function Tooltip({ text }: { text: string }) {
const ref = useRef<HTMLDivElement>(null);
const [height, setHeight] = useState(0);
useLayoutEffect(() => {
const node = ref.current;
if (!node) return;
setHeight(node.getBoundingClientRect().height);
}, [text]);
return (
<div ref={ref} style={{ marginTop: height > 40 ? 8 : 0 }}>
{text}
</div>
);
}Scroll restore without flash:
useLayoutEffect(() => {
listRef.current?.scrollTo(0, savedScrollTop);
}, [items]);⚠️ Pitfalls
- Using layout effects for data fetching—blocks paint; use
useEffect/ loaders. - Infinite loops: layout effect sets state that changes layout deps every time.
- SSR mismatch / warnings—prefer
useEffectunless measurement is required. - Heavy computation in layout effect → jank.
🔗 Related
- useEffect.md — default effect
- useRef.md — DOM refs
- performance.md — paint timing
- hooks.md — rules
- concurrent.md — rendering model