react项目中使用react-transition-group做路由切换动画遇到的问题
问题描述:
在学习react项目时,灵光乍现想用一用vue项目路由切换的效果,就去网上搜集了一些资料,后来测试就用了这两个插件:
npm install framer-motion
npm install react-transition-group
最开始用的 framer-motion 插件:
import { AnimatePresence, motion } from "framer-motion";
import style from "./content.module.scss";
const routeVariants = {
animate: {
opacity: 1,
transform: "translateX(0)",
},
exit: {
opacity: 0,
transform: "translateX(30px)",
transition: {
duration: 0.5,
},
},
};
export default function Content() {
const { pathname } = useLocation();
const currentOutlet = useOutlet();
return (
<div className={style.content}>
<AnimatePresence mode="wait" initial={false}>
<motion.div
key={pathname}
variants={routeVariants}
animate="animate"
exit="exit"
>
{/* 这里不能使用<Outlet />标签 */}
{currentOutlet}
</motion.div>
</AnimatePresence>
</div>
);
}
后来发现使用这个插件的时候,如果快速切换路由会出BUG,导致页面消失不见.具体什么原因不得而知,知道的兄弟可以评论区留言.
最终使用react-transition-group插件
import { CSSTransition, SwitchTransition } from "react-transition-group";
import style from "./content.module.scss";
export default function Content() {
const { pathname } = useLocation();
const currentOutlet = useOutlet();
return (
<div className={style.content}>
<SwitchTransition mode="out-in">
<CSSTransition
key={pathname}
appear={true}
timeout={300}
classNames="fade"
unmountOnExit
>
{/*
路由懒加载时,动画挂在到Suspense,导致动画无法挂在到路由组件上,动画无法执行
Suspense和CSSTransition之间建一个盒子充当容器
*/}
<div>{currentOutlet}</div>
</CSSTransition>
</SwitchTransition>
</div>
);
}
最开使用这个插件也出现了一些问题:
- 切换路由动画时会发现,动画是进入路由之后才开始有退场动画==>入场动画.本来应该是(旧组件退出动画)==>(新组件入场动画)
解决方法: 不要使用
<Outlet />标签,使用HookuseOutlet()就可以解决这个问题.
- 如果路由使用了懒加载并且使用
useOutlet(),就会出现下面这个情况;如果使用了<Outlet />就不会出现这个情况,但是也会出现上述问题.
页面会报错 Cannot read properties of undefined (reading 'baseVal'),其原因是因为路由懒加载会有一个
<Suspense>路由组件<Suspense/>切换路由由于是懒加载所以一开始是没有容器的就会出现报错.
解决方法:
在 CSSTransition和Suspense之间在创建一个容器div就可以解决这个问题.切换到懒加载的路由时div是存在的,就不会报错啦.