JAVASCRIPT
Measure DOM Element Dimensions Synchronously with useLayoutEffect
Learn how to use React's useLayoutEffect hook to synchronously measure and adjust DOM element dimensions immediately after render, preventing visual flickering.
import React, { useState, useRef, useLayoutEffect } from 'react';
function ResizableBox() {
const [height, setHeight] = useState(100);
const boxRef = useRef(null);
useLayoutEffect(() => {
if (boxRef.current) {
// Simulate some dynamic content or external factor changing height
const newCalculatedHeight = boxRef.current.scrollHeight + 20; // Example adjustment
if (newCalculatedHeight !== height) {
setHeight(newCalculatedHeight);
}
}
}, [height]); // Depend on height to re-evaluate if it changes externally
return (
<div style={{ padding: '10px', border: '1px solid #ccc', marginBottom: '10px' }}>
<p>Box Height: {height}px</p>
<div
ref={boxRef}
style={{
width: '200px',
height: height,
backgroundColor: '#e0f7fa',
overflow: 'hidden',
resize: 'vertical',
minHeight: '50px',
border: '1px dashed #00bcd4',
}}
>
This box adjusts its height using useLayoutEffect.
<br />
Content might grow dynamically.
<br />
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
</div>
<button onClick={() => setHeight(h => h + 50)}>Increase Height</button>
</div>
);
}
// Usage example in another component:
// function App() {
// return <ResizableBox />;
// }
How it works: `useLayoutEffect` is similar to `useEffect` but runs synchronously *after* all DOM mutations and *before* the browser paints. This makes it ideal for reading DOM layout and performing synchronous re-renders, such as measuring an element's size or position and then adjusting styles. It prevents visual flickering that might occur if these adjustments were made in `useEffect` (which runs asynchronously after paint).