Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUG] AnimatePresence not working with layout animations #1983

Open
nandanmen opened this issue Feb 25, 2023 · 3 comments
Open

[BUG] AnimatePresence not working with layout animations #1983

nandanmen opened this issue Feb 25, 2023 · 3 comments
Labels
bug Something isn't working

Comments

@nandanmen
Copy link

1. Read the FAQs 馃憞

2. Describe the bug

Not sure if I'm just doing something wrong here but it seems AnimatePresence doesn't reliably perform the exit animation when the children has the layout prop:

CleanShot.2023-02-25.at.08.12.04.mp4

More specifically, it seems that the animation won't happen if a current exit animation is in progress. If you click on "remove" slowly (i.e. wait for the exit animation to finish and the element to be removed from the DOM), then the exit animations work as expected.

3. IMPORTANT: Provide a CodeSandbox reproduction of the bug

https://codesandbox.io/s/affectionate-alex-mjc72j?file=/src/App.js

4. Steps to reproduce

  1. Click on "add" to extend the list
  2. Click on "remove" a few times quickly

5. Expected behavior

Multiple numbers can perform the exit animation at the same time.

7. Environment details

MacOS Monterey 12.6.3, Chrome 110.0.5481.177

FAQs

Framer Motion won't install

Framer Motion 7+ uses React 18 as a minimum. If you can't upgrade React, install the latest version of Framer Motion 6.

height: "auto" is jumping

Animating to/from auto requires measuring the DOM. There's no perfect way to do this and if you have also applied padding to the same element, these measurements might be wrong.

The recommended solution is to move padding to a child element. See this issue for the full discussion.

Type error with AnimateSharedLayout

AnimateSharedLayout was deprecated in 5.0. Refer to the upgrade guide for instructions on how to remove.

Preact isn't working

Framer Motion isn't compatible with Preact.

AnimatePresence isn't working

Have all of its immediate children got a unique key prop that remains the same for that component every render?

// Bad: The index could be given to a different component if the order of items changes
<AnimatePresence>
  {items.map((item, index) => <Component key={index} />)}
</AnimatePresence>
// Good: The item ID is unique to each component
<AnimatePresence>
  {items.map((item, index) => <Component key={item.id} />)}
</AnimatePresence>

Is the AnimatePresence correctly outside of the controlling conditional? AnimatePresence must be rendered whenever you expect an exit animation to run - it can't do so if it's unmounted!

// Bad: AnimatePresence is unmounted - exit animations won't run
{isVisible && (
  <AnimatePresence>
    <Component />
  </AnimatePresence>
)}
// Good: Only the children are unmounted - exit animations will run
<AnimatePresence>
  {isVisible && <Component />}
</AnimatePresence>
@nandanmen nandanmen added the bug Something isn't working label Feb 25, 2023
@Rikveet
Copy link

Rikveet commented Mar 20, 2023

Might not be related.
In my project, I had a similar issue.
I might have not have implemented it correctly

<form>
 <motion.div layout={'position'}>Title</motion.div>
 <motion.div layout={'position'}>Users</motion.div>
 <motion.div layout={'position'}>Inputs</motion.div>
 <AnimatePresence>conditional component</AnimatePresence>
</form>
Untitled.video.-.Made.with.Clipchamp.mp4

if I add the mode type poplayout it starts to work in a way.

<form>
 <motion.div layout={'position'}>Title</motion.div>
 <motion.div layout={'position'}>Users</motion.div>
 <motion.div layout={'position'}>Inputs</motion.div>
 <AnimatePresence mode={'popLayout'}>conditional component</AnimatePresence>
</form>
Untitled.video.-.Made.with.Clipchamp.1.mp4

I think the reason why it doesn't work in the first case is that the layout does not wait for animate presence to conclude. It's code either runs concurrently or before animate presence is concluded.
I might have just implemented it incorrectly. Thought this would be helpful.

@tarngerine
Copy link

tarngerine commented Dec 14, 2023

not sure if it's the same issue but i had a layoutId animation + animatepresence exit animation that used to work, but broke upon updating to latest.

i bisected it to v9.0.3 as the culprit. try downgrading to 9.0.2 (if you were previously on an old version like me) and see if it works

@g-popovic
Copy link

g-popovic commented Feb 21, 2024

I also have this issue. Seemingly when rendering a motion.div with the layout prop inside of an AnimatePresence component, if the motion div child has a change in width or something, it's not animated at all, it just snaps into place. Rendering this motion elsewhere in my project resulted in it working correctly. So yes it seems rendering motion.div with layout={true} inside of AnimatePresence is currently broken (even on v9.0.2), quite unfortunate.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

4 participants