How useLayoutEffect Works in React and How Does it Differ from useEffect?
useLayoutEffect is a hook in React similar to useEffect, but with one key difference: it executes immediately after DOM changes, but before the browser applies changes and displays them on screen.
How Does useLayoutEffect Work?
-
Synchronous effect. Unlike
useEffect, which executes asynchronously after render,useLayoutEffectexecutes synchronously immediately after React updates DOM, but before browser paints changes on screen. This can be useful if you need to measure DOM or perform actions that may affect rendering. -
For DOM work. This hook is more often used when you need to do something with DOM directly (e.g., measure element sizes or apply styles before browser displays updates).
useLayoutEffect Usage Example
import { useState, useLayoutEffect, useRef } from "react";
function LayoutEffectExample() {
const [width, setWidth] = useState(0);
const divRef = useRef(null);
useLayoutEffect(() => {
// Synchronously measure element width before render
if (divRef.current) {
setWidth(divRef.current.getBoundingClientRect().width);
}
}, []); // Effect will fire only once
return (
<div>
<div ref={divRef} style={{ width: "100%" }}>
<p>Element width: {width}px</p>
</div>
</div>
);
}
Differences from useEffect
- Execution timing:
useEffectexecutes asynchronously after browser completes rendering and paints changes.useLayoutEffectexecutes synchronously immediately after DOM changes, but before browser applies changes and displays them.
- Usage:
useEffectis suitable for most side effects like data fetching or subscriptions.useLayoutEffectis used when you need to synchronously work with DOM, for example, for measurements or changes that must occur before painting.
- Performance:
useEffectdoesn't block rendering as it executes after browser displays changes.useLayoutEffectcan block rendering if it performs complex calculations or operations that require time.
Important about useLayoutEffect:
useLayoutEffect can block rendering, so it should only be used when truly necessary (e.g., for measurements or synchronous DOM changes).