UNPKG

@ryvora/react-use-layout-effect

Version:

πŸ“πŸ“ Synchronous layout effect hook for React. Measure and update before paint!

52 lines (37 loc) β€’ 2.11 kB
# use-layout-effect πŸ“πŸ“ Hey DOM Measurer! 🧐 The `use-layout-effect` hook is a version of `useEffect` that fires **synchronously** after all DOM mutations. This is crucial when you need to read layout from the DOM (like getting an element's size or position) and then synchronously re-render based on that information before the browser has a chance to paint. It's like `useEffect`, but it gets to cut in line πŸšΆβ€β™€οΈβž‘οΈπŸšΆβ€β™‚οΈ to do its work _before_ the user sees any visual updates! ## `useEffect` vs `useLayoutEffect` - **`useEffect`**: Runs _asynchronously_ after render and after the browser has painted. Good for most side effects (data fetching, subscriptions). - **`useLayoutEffect`**: Runs _synchronously_ after render but _before_ the browser paints. Good for DOM measurements that need to trigger a synchronous re-render. **Warning:** Because `useLayoutEffect` is synchronous, it can block visual updates if you do too much work in it. Prefer `useEffect` when possible! ## When to Use It: - Measuring DOM elements (e.g., getting `getBoundingClientRect()`). - Manually changing the DOM (though this should be rare in React) and needing to ensure it's done before paint. - Animating based on layout changes. ## Basic Usage: ```tsx import React, { useState, useLayoutEffect, useRef } from 'react'; function MyComponent() { const [width, setWidth] = useState(0); const myDivRef = useRef<HTMLDivElement>(null); useLayoutEffect(() => { // This runs after the div is rendered but before the browser paints if (myDivRef.current) { console.log('Measuring width in useLayoutEffect'); setWidth(myDivRef.current.offsetWidth); } // If setWidth here causes a re-render, it happens synchronously }, []); // Empty array means it runs once after initial layout return ( <div> <div ref={myDivRef} style={{ width: '50%', border: '1px solid black' }}> I am a div! </div> <p>The div's calculated width is: {width}px</p> </div> ); } ``` Use it wisely to keep your UI snappy and avoid visual flickers! βœ¨πŸ’¨