useOnceLayoutEffect
A Hook that avoids React18 useLayoutEffect run twice
useOnceLayoutEffect is a variant of useLayoutEffect that guarantees the effect callback executes only once, even under React 18’s Strict Mode which intentionally double-invokes effects during development. It uses the same WeakSet-based tracking mechanism as useOnceEffect but runs with useLayoutEffect timing — synchronously after DOM mutations and before the browser paints.
When to Use
- Performing DOM measurements or mutations that must happen exactly once before paint, without being duplicated by React 18 Strict Mode
- Initializing layout-dependent third-party libraries (e.g., chart or animation libraries that manipulate the DOM directly) that break when initialized twice
- Any case where you need
useLayoutEffectsemantics with guaranteed single-execution
Notes
- Layout timing: Runs synchronously after all DOM mutations, before the browser repaints. This can block visual updates if the effect is slow.
- React 18 Strict Mode: Prevents the double-invocation that React 18 performs in development to help detect side-effect issues.
- See also
useOnceEffectfor theuseEffect-timed equivalent, anduseIsomorphicLayoutEffectfor SSR-safe layout effects.
Usage
Live Editor
function Demo() { const [updateEffect, setLayoutEffect] = useState(0); const [onceLayoutEffect, setOnceLayoutEffect] = useState(0); useOnceLayoutEffect(() => { setOnceLayoutEffect(onceEffect => onceEffect + 1); }, []); useLayoutEffect(() => { setLayoutEffect(effect => effect + 1); }, []); return ( <div> <div>onceEffect: {onceLayoutEffect}</div> <br /> <div>effect: {updateEffect}</div> </div> ); };
Result