useIsomorphicLayoutEffect
Usage
import { animated, useSpring, useIsomorphicLayoutEffect } from '@react-spring/web'
const MyComponent = ({position}) => {
const [springs, api] = useSpring(() => {
y: 0,
x: 0,
}, [])
useIsomorphicLayoutEffect(() => {
api.start({
from: {
x: 0,
y: 0,
},
to: {
x: position.x,
y: position.y,
}
})
},[position])
return <animated.div style={springs} />
}
Why do we need this?
When we want to perform side-effects caused by rendering a component we need to
use useEffect
or useLayoutEffect
.
Now, the latter, useLayoutEffect
in our opinion, is better for animations because it renders
"before the browser has a chance to paint", therefore if you want to prepare a node e.g. a div
for animation before actually animating it, it's probably better to ensure no paint happens, otherwise
you might get a sort of UI tear where the item suddenly jumps to a new position.
Neither of the above effect hooks run on the server, however, useLayoutEffect
causes react warnings
when server-side rendering your pages (if you're using nextjs for example). So it encourages you
to move the code to useEffect
. However, as we described above this isn't best for animations.
What does it do?
This is where our useIsomorphicLayoutEffect
utility hook comes in. By performing a simple (yet robust) check,
the hook correctly returns useEffect
for server-side environments and useLayoutEffect
for client-side
environments, thus the best of both worlds in this case.
Typescript
The type signature will be identical to the signatures of useEffect
and useLayoutEffect
installed in
your project, but just to save you time, it's here below:
function useIsomorphicLayoutEffect(effect: () => (void | () => void), deps?: ReadonlyArray<unknown>)