react-transition-group路由切换动画遇到的问题

425 阅读2分钟

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>
  );
}

最开使用这个插件也出现了一些问题:

  1. 切换路由动画时会发现,动画是进入路由之后才开始有退场动画==>入场动画.本来应该是(旧组件退出动画)==>(新组件入场动画)

tutieshi_640x263_7s.gif 解决方法: 不要使用<Outlet />标签,使用HookuseOutlet()就可以解决这个问题.

  1. 如果路由使用了懒加载并且使用useOutlet(),就会出现下面这个情况;如果使用了<Outlet />就不会出现这个情况,但是也会出现上述问题.

tutieshi_640x263_5s.gif 页面会报错 Cannot read properties of undefined (reading 'baseVal'),其原因是因为路由懒加载会有一个<Suspense>路由组件<Suspense/>切换路由由于是懒加载所以一开始是没有容器的就会出现报错.

解决方法: 在 CSSTransitionSuspense之间在创建一个容器div就可以解决这个问题.切换到懒加载的路由时div是存在的,就不会报错啦.