Skip to main content

useIsomorphicLayoutEffect

useLayoutEffect that quietly becomes useEffect during server rendering.

Usage​

import { useIsomorphicLayoutEffect } from '@multinaire/expo-ui';

function MeasuredBox() {
const [width, setWidth] = useState(0);

useIsomorphicLayoutEffect(() => {
setWidth(ref.current.getBoundingClientRect().width);
}, []);

return <View ref={ref} />;
}

The signature is useLayoutEffect's — same effect callback, same dependency array.

Why this exists​

React warns when useLayoutEffect is used during SSR, because a layout effect's work can't be encoded into the server-rendered HTML. The usual fix — switching to useEffect — silences the warning but changes behaviour on the client too: a passive effect resolves after the browser paints, so any correction it makes (a measured size, a theme colour) flashes the placeholder value first.

This hook keeps both: useEffect on the server, where the effect never actually runs and the swap is a true no-op, and useLayoutEffect everywhere else, so client-side corrections still land before the first paint.

@multinaire/expo-ui uses it internally in useIsHydrated and useThemeColorSync. It's exported so your own pre-paint effects can be SSR-safe the same way.

Platform Notes​

  • On native there's no SSR step, so this is always useLayoutEffect.
  • The swap is decided once at module load from Platform.OS and typeof window, not per render — so the identity of the hook never changes between renders, which is what keeps React's rules-of-hooks happy.