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.