Home > @cascadiacollections/fluentui-compat > useIsomorphicLayoutEffect
useIsomorphicLayoutEffect variable
Hook that uses useLayoutEffect on the client and useEffect on the server.
React throws a warning when using useLayoutEffect during server-side rendering because layout effects don't run on the server. This hook provides a drop-in replacement that: - Uses useLayoutEffect in the browser for synchronous DOM updates - Uses useEffect on the server to avoid SSR warnings - Maintains the same API as useLayoutEffect
**When to use**: - Measuring DOM elements and updating state before paint - Synchronizing with external systems before browser paint - Reading layout information and causing a synchronous re-render - Any case where you need useLayoutEffect but also support SSR
**When NOT to use**: - Most effects should use regular useEffect instead - Only use this when timing relative to browser paint matters - If you don't need SSR support, use useLayoutEffect directly
Signature:
useIsomorphicLayoutEffect: typeof React.useEffect
Example 1
// Measure element size after render but before paint
function TooltipWithDynamicPosition() {
const [position, setPosition] = useState({ top: 0, left: 0 });
const tooltipRef = useRef<HTMLDivElement>(null);
useIsomorphicLayoutEffect(() => {
if (tooltipRef.current) {
const rect = tooltipRef.current.getBoundingClientRect();
setPosition({
top: rect.height,
left: rect.width / 2
});
}
}, []);
return (
<div ref={tooltipRef} style={{ top: position.top, left: position.left }}>
Tooltip
</div>
);
}
Example 2
// Sync with external library before paint
function ChartComponent({ data }: { data: ChartData }) {
const chartRef = useRef<HTMLCanvasElement>(null);
const chartInstanceRef = useRef<Chart | null>(null);
useIsomorphicLayoutEffect(() => {
if (chartRef.current) {
// Initialize chart synchronously before paint
chartInstanceRef.current = new Chart(chartRef.current, {
type: 'bar',
data: data
});
}
return () => {
chartInstanceRef.current?.destroy();
};
}, [data]);
return <canvas ref={chartRef} />;
}
Example 3
// Update ref synchronously for event handlers
function ScrollComponent() {
const [scrollTop, setScrollTop] = useState(0);
const scrollRef = useRef(0);
useIsomorphicLayoutEffect(() => {
// Update ref synchronously so event handlers have current value
scrollRef.current = scrollTop;
}, [scrollTop]);
const handleScroll = useCallback(() => {
// scrollRef.current is guaranteed to be up-to-date
console.log('Current scroll:', scrollRef.current);
}, []);
return <div onScroll={handleScroll}>Content</div>;
}