I am new with react-spring. I am having trouble animating a component whenever it unmounts. I have a simple card with an onClick handler that's responsible for conditionally displaying my Overlay component. The animation works fine when mounting (from & enter works), but when closing the overlay, the component just disappears without animation (leave does not work). I suspect it's because of the conditional rendering of the component but I've been struggling for hours trying to find a solution for this one. Any help would be appreciated!
My current code: https://codesandbox.io/s/dry-leftpad-h3vmv
What I'm trying to achieve: https://codesandbox.io/s/048079xzw
P.S. The latter is using mauerwerk's lib. I don't want to use that.
What you were missing is this:
return expand.map(({ item, props, key }) => (
item && <animated.div
// ...etc
When you're controlling the mounting of a single component with useTransition
, you need to conditionally render it based on the item
being passed. In your case, when it's false
it won't render (which will unmount if already mounted) and when it's true
it will render (mount if unmounted).
Here's a working sandbox forked from yours: https://codesandbox.io/s/infallible-agnesi-cty5g.
The first argument to useTransition
is the list you want to transition. That watches for changes and sends back an array mapped with each item, a key and a style object (props
) based on whether the item is truthy (entering) or falsy (leaving). So for a transition that mounts/unmounts a single element, conditionally rendering based on the truthiness of the item is key.
Check out the examples again here and you'll see the differences between transitioning a list, a toggle between two elements, and a single item.
For a list, no need to check for the existence of the item because the array changes.
For toggling between two elements, you use the truthiness of item
to determine which element to render.
For a single element, item
determines whether to render at all. This means it won't mount initially when you default to false
, and will make sure you don't render 2 items whenever your isActive
value changes.