I wanted the button to move down to accomodate for a new row added. So I put layout
on the MotionButton
(Which is just a motion(...)
wrapped component).
<div className="grid gap-5">
<AnimatePresence>
{flightDates.map((f, index) => (
<motion.div
key={index}
exit={{
opacity: 0,
y: 10,
}}
initial={{
opacity: 0,
y: 10,
}}
animate={{
opacity: 1,
y: 0,
}}
transition={{
duration: 0.2,
}}
>
<FlightDateRow
key={index}
onChange={(updatedFlight) => {
setFlightDates((prev) => {
const newFlights = [...prev]
newFlights[index] = {
...newFlights[index],
...updatedFlight,
}
return newFlights
})
}}
onDelete={removeFlightDate(index)}
canDelete={flightDates.length > 1}
{...f}
/>
</motion.div>
))}
</AnimatePresence>
<MotionButton
className="w-min pl-2"
variant="secondary"
onClick={addNewFlightDate}
layout
transition={{
duration: 0.2,
}}
>
<PlusMini className="mr-2" />
Flight
</MotionButton>
</div>
2
Answers
I ended up having to wrap my button in a
<motion.div layout></motion.div>
instead of converting the button to aMotionButton
. My button component would cause a remount to occur when clicking the button. So relying on an outer div to manage position within the layout fixed it.I’ve asked you in the comments if you could add the following debugging statement:
Because I suspected you’re component was being re-mounted. This would explain the behaviour, since your button would trigger its unmount animation, and then its mount animation.
You confirmed this was indeed the case:
Since you haven’t provided much context in the question I can only guess why it’s being re-mounted. Here is a scenario that is probably the most common.
Say though some sort of logic the structure of you output JSX changes from:
to:
This causes
<A>
to unmount, which in turn causes all the children of<A>
also unmount. Then<B>
is mounted with all its children. Due to the parent component change ofYourButton
,YourButton
will also be unmounted and mounted.I don’t know if this is the exact cause, since there are other reasons why a component might re-mount. But this is in my opinion the most likely cause. It could be be the internals of Framer Motion it could be something else.
I hope this helps your understanding of why this problem happens and are happy to see you already found a solution to your issue in your own answer.