If you use server rendering, keep in mind that neither useLayoutEffect
nor useEffect
can run until the JavaScript is downloaded.
You might see a warning if you try to useLayoutEffect
on the server. Here's two common ways to fix it.
If this effect isn't important for first render (i.e. if the UI still looks valid before it runs), then useEffect
instead.
function MyComponent() {
useEffect(() => {
// ...
});
}
Like useLayoutEffect
, it won't run on the server, but it also won't warn.
If UI looks broken with useEffect
but gets fixed by useLayoutEffect
, it means that this component doesn't look right until the effect runs. However, that means the server-rendered HTML version of it won't look right until JavaScript loads anyway. So server-rendering it brings no benefit and shows a confusing UI.
To fix this, you can delay showing that component until after the client side JS loads and hydrates the component. To exclude a Child
that needs layout effects from the server-rendered HTML, you can render it conditionally:
function Parent() {
const [showChild, setShowChild] = useState(false);
// Wait until after client-side hydration to show
useEffect(() => {
setShowChild(true);
}, []);
if (!showChild) {
// You can show some kind of placeholder UI here
return null;
}
return <Child {...props} />;
}
function Child(props) {
useLayoutEffect(() => {
// This is where your layout effect logic can be
});
}
For example, this is handy for jQuery plugins which can be initialized later.
If you have some use case that isn't covered, please report a complete minimal code example here and we'll try to help.
I suppose the initial idea is little bit not valid. Warning said that you should not use
useLayoutEffect
in components what can be rendered on SSR.Consider situation when we have some component and this component used on two pages.
I open first page via SSR and hydration (useLayoutEffect does nothing on SSR, and make something after hydration),
and I navigate to page 2 on client side (without SSR) and get page 2 layout where our components used, it does something with
useLayoutEffect
, all is okay.BUT: My console spammed with tons of warnings. Suppose I read it and replace all
useLayoutEffect
withuseEffect
, and what I get?It will be the same in case of opening page via SSR (no-op on SSR, action of client), but when navigate to page 2, I notice glitch for some time because of using
useLayout
instead ofuseLayoutEffect
.Why react forces me to make application worse than it can be?
Long story short: component with
useLayoutEffect
maybe used not only while SSR, but after client's routing, so the use of theuseLayoutEffect
should be valid.