简体   繁体   中英

Framer Motion AnimatePresence doesn't execute when changing routes

I'm having trouble with the Framer Motion library, particularly the AnimatePresence transition. I can get it to work under normal circumstances, but when I wrap my Routes in a custom implementation, I cannot get the exit animation to work.

When I navigate to a different route, I confirmed using the useEffect hook at the component is unmounting, yet the exit animation is not triggered by the parent AnimatePresence.

Any help would be greatly appreciated.

Here is my code:

App.ts

const App = () => {

    const auth: AuthContextState = useContext(AuthContext);
    const db: FirestoreContextProps = useContext(FirestoreContext);

    const components = {
        home: HomeScreen,
        classes: ClassScreen,
        users: UserScreen,
        login: LoginScreen
    }



    return (
        <Background>
            <Navbar/>
            <Dashboard isLoggedIn={auth.data.authenticated}>
                <AnimatedRoutes>
                    <RouteTransition path={`/home`} key={0}>
                        <HomeScreen key={0} />
                    </RouteTransition>
                    <RouteTransition path={`/classes`} key={1}>
                        <ClassScreen key={1} />
                    </RouteTransition>
                    <RouteTransition path={`/users`} key={2}>
                        <UserScreen key={2} />
                    </RouteTransition>
                    <RouteTransition path={'/login'} key={3}>
                        <LoginScreen key={3} />
                    </RouteTransition>
                    <RouteTransition exact path={'/'} key={4}>
                        <Redirect to={'/home'}/>
                    </RouteTransition>
                </AnimatedRoutes>
            </Dashboard>
        </Background>
    );
}

Animated Routes:

type Props = {
    exitBeforeEnter?: boolean
    initial?: boolean
}

export const AnimatedRoutes: FC<Props> = ({
    children,
    exitBeforeEnter = true,
    initial = false,
}) => {

    return (
        <AnimatePresence exitBeforeEnter={exitBeforeEnter} initial={initial}>
            <Switch>
                {children}
            </Switch>
        </AnimatePresence>
    )

}

type RouteProps = {
    key: number
    exact?: boolean
    path: string
    slide?: number
    slideUp?: number
}

export const RouteTransition: FC<RouteProps> = ({

    children,
    key,
    exact = false,
    path,
    slide= 0,
    slideUp = 0,
    ...rest

}) => {

    return (
        <Route path={path} exact={exact} {...rest}>
            <MountTransition key={key} >
                {children}
            </MountTransition>
        </Route>
    )
}

Mount Transition:

type Props = {
    key: number
    slide?: number
    slideUp?: number
}


const Container = styled(motion.div)`
    display: flex;
    height: 100%;
    width: 100%;
`

export const MountTransition: FC<Props> = ({
    children,
    key,
    slide = 0,
    slideUp = 0,
}) => {
    return (
        <Container
            key={key}
            initial={{opacity: 0, x: slide, y: slideUp}}
            animate={{opacity: 1, x: 0, y: 0}}
            exit={{opacity: 0, x: slide, y: slideUp}}
            transition={{type: 'tween', duration: 2, ease: 'easeInOut'}}
        >
            {children}
        </Container>
    )
}

Try something like this:

<Route
   render={({location}) => {
     return (
       <AnimatePresence exitBeforeEnter>
          <Switch location={location} key={location.key}>
             <Route .../>
             <Route .../>
             <Route .../>
           </Switch>
       </AnimatePresence>
     )
   }}
 />

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM