UseLayoutEffect

Identical to useEffect(), useLayoutEffect() differs in that it will run after React has committed updates to the DOM. useLayoutEffect() is used in rare cases when you need to calculate the distance between elements after an update or do other post-update calculations/side-effects.

The signature is identical to useEffect(), but it fires synchronously after all DOM mutations. Use this to read the layout from the DOM and synchronously re-render. Updates scheduled inside useLayoutEffect will be flushed synchronously before the browser has a chance to paint.

Unlike componentDidMount or componentDidUpdate, effects scheduled with useEffect() don't block the browser from updating the screen. This makes your app feel more responsive. The majority of effects don't need to happen synchronously. In the uncommon cases where they do (such as measuring the layout), there is a separate useLayoutEffect Hook with an API identical to useEffect.

If we were to use useEffect() in place of useLayoutEffect() below, we will see the box flickers momentarily in a jumpy manner when it is clicked.
const Message = ({boxRef, children}) => { const msgRef = React.useRef(null); React.useLayoutEffect(() => { const rect = boxRef.current.getBoundingClientRect(); msgRef.current.style.top = `${rect.height + rect.top}px`; }, []); return <span ref={msgRef} style={{position:'relative', border:'1px solid red'}}> {children} </span>;};const App = () => { const [show, setShow] = React.useState(false); const boxRef = React.useRef(null); return ( <div> <div ref={boxRef} onClick={() => setShow(prev => !prev)} style={{position:'absolute',width:'100px',height:'100px', background:'green',color:'white'}}> Click me </div> {show && <Message boxRef={boxRef}>Foo bar baz</Message>} </div> );};ReactDOM.render(<App />, document.querySelector("div"));