motion: AnimatePresence exit not working for me...

Dunno if this is a bug or if i’m doing something wrong, but the exit prop does not seem to be working for me. Here is my code:

<AnimatePresence exitBeforeEnter>
  <Container
    {...props}
    initial={{
      opacity: 0
    }}
    animate={{
      opacity: 1,
      transition: { 
        delay: 3,
        duration: 5
      }
    }}
    exit={{
      opacity: 0,
      transition: { 
        delay: 3,
        duration: 5
      }
    }}
  >
    {props.children}
  </Container>
</AnimatePresence>

…based on the code above, i am expecting the component to wait 3 seconds, then fade out over 5 seconds, then wait 3 seconds, then fade in over five seconds.

what actually happens is that the component fades out instantly, then about six seconds pass, then it fades in over 5 seconds…so, the piece that does not seem to be working is the fade out over 5 seconds as the component exits…

do you think this might be a bug or m i doing something incorrect here?

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Reactions: 8
  • Comments: 17 (1 by maintainers)

Commits related to this issue

Most upvoted comments

@amcc The direct child(ren) of AnimatePresence need to be either changing key or mounting/unmounting to fire exit animations. Here, the direct child is Container, which never does either. So this isn’t going to work.

Additionally, AnimatePresence needs to be rendered consistently to track changes to its children. This is an unavoidable constraint of React. Although Transition here is being rendered by Layout in a consistent way, Layout itself is being mounted/unmounted every render. You can see this by adding a useEffect:

const Layout = props => {
  React.useEffect(() => {
    console.log("mount")
  }, [])

This will fire every time a page changes. This means that each AnimatePresence component is an entirely new instance of the component, so it has no connection to any other AnimatePresence components that may have been rendered in the past.

Your usage in the example above is correct - as long as Transition itself isn’t remounting. Which it seems to be here. I don’t know enough about the Gatsby template system to know if there’s a way around this.

you are doing something wrong. AnimatePresence will detect which children has been mounted or unmounted. You have Container that is ALWAYS rendered as a children. It will never animate because Container is always mounted; it never unmounts, so you wont get any animation

On top of that, you also have to give “key” prop to each children, so that AnimatePresence can detect them.

Fought this for a while to but the problem resulted from me using the <a> tag instead of react’s <Link> so the change in pathname wasn’t detected for AnimatePresence to fire the exit. Just putting this out here as something to look at incase none of the solutions above fixed your bug when implementing route based animation

This can be closed?

Any updates on this?