Noticing clunky unmount behaviour when using useTransition to animated list items in/out as the list changes.
Here's a CodeSandbox showing the behaviour: https://codesandbox.io/s/91pw8o9x0w.
As you can see, the leaving items animate out nicely, but then the space each one occupied takes a long time to disappear (and disappears suddenly).
Is there a simple way to animate these items in/out more smoothly?
Edit:
Ideally, I'd like to animate the old items out before animating the new items in, and I'd like the new items to animate into the correct position as soon as the old items are no longer visible.
looks good to me, in that it works as expected. if you have padding, even if the item has zero height/width, it will still claim space. that space will snap away on unmount. the items also seem to unmount fine, you have a trail, so unmount is delayed. If you remove paddings and make them shrink you can get a better picture of what's going on: https://codesandbox.io/s/6lv9zno4p3
A good way to use padding in situations where objects are stacked is to wrap them. See: https://codesandbox.io/embed/26mjowzpr (they have margins and shadows), but can be collapsed to zero (which unfortunately you don't see there, but it works)
Thank you so much for your help! Those examples are cool.
In your first example (https://codesandbox.io/s/6lv9zno4p3), I notice that the new items animate in before the old items animate out; is it possible to reverse this sequence?
I鈥檓 trying to take the normal behaviour that exists when filtering non-animated gallery items:
...and enhance it by animating out the old items before animating in the new ones. I don鈥檛 want both groups to ever appear onscreen at the same time and would like the new group to be in the correct location when it first appears (i.e. old group already unmounted and its space released).
Is this sequence possible with useTransition (or another hook)?
(I鈥檓 hoping to use this approach frequently for filterable galleries on client sites.)
this happens because trail basically adds up, for now it's not configurable: https://github.com/react-spring/react-spring/blob/master/src/useTransition.js#L179-L232
What could work is the useSprings hook its super powerful, but it doesn't have transitions retaining stuff, so number of items gotta be static.
this happens because trail basically adds up, for now it's not configurable: https://github.com/react-spring/react-spring/blob/master/src/useTransition.js#L179-L232
I see... But even with trail disabled, the new items mount and are appended to the list before the old items unmount. Is it possible to delay mounting the new items until the old items have unmounted?
In my use case (a gallery where each item is fairly tall), the old items animate out (which looks nice) while the new items are appended to the end of the list offscreen. Once the old items snap out, the new items seem to enter without an entrance animation, but that's because the entrance animation already happened too far down the page to see it.
So, I'd like to delay the entrance animation/mounting of new items (i.e. don't append them to the list) until the exit animation/unmounting of old items is complete. I'm happy to remove the trail if that helps.
Is that possible?
(My understanding is that useSprings can't handle unmount animations, but let me know if I'm wrong about that.)
we have to make trail configurable in that case, or at least trail order (enter > update > leave). do have any ideas how you'd like to control that?
Hmm...maybe with an order prop on useTransition (assuming you're asking about the API)?
For example:
const [items, set] = useState([1,2,3,4])
const trans = useTransition(items, item => item.key, {
from: { transform: 'translate3d(0,-40px,0)' },
enter: { transform: 'translate3d(0,0px,0)' },
leave: { transform: 'translate3d(0,-40px,0)' },
order: ['leave', 'enter', 'update'] // seems to default to ['enter', 'update', 'leave']
})
return trans.map(({ item, props, key }) => (
<animated.div
key={key} style={props}>{item}</animated.div>
))
Let me know if I misunderstood the question!
It would also be nice to be able to sequence these lifecycles even if no trail is used on the individual items.
In other words, even with no trail, have the option to complete leave before starting enter.
Thanks for considering this @drcmda!
For anyone running into this use case in the meantime, the compromise I'm using for now is to cancel the leave transition entirely:
const itemsWithTransitions = useTransition(items, item => item, {
from: { ... },
enter: { ... },
leave: { ... },
config: (item, state) =>
state === 'leave' ? { duration: 0 } : config.default,
})
This isn't as nice as a leave + enter animation sequence will be, but it prevents the entering and leaving items from being shown at the same time.
item => item can be "null" btw. it's shorter. : ) i will try to do something about the ordering issue meanwhile.
It would also be nice to be able to sequence these lifecycles even if no trail is used on the individual items.
In other words, even with no trail, have the option to complete
leavebefore startingenter.
@ooloth Can you open a new issue with this feature request, please?
Is there a chance that "fix" for this was implemented? Can someone point me in the right direction?
Most helpful comment
item => item can be "null" btw. it's shorter. : ) i will try to do something about the ordering issue meanwhile.