用 react-transition-group 实现路由切换动画

1,755 阅读3分钟

技术栈: React 18、React Router 6

在现代 Web 开发中,让用户体验变得更流畅和更有视觉冲击力是大家追求的目标。React 作为一个广受欢迎的前端框架,提供了很多工具来提升应用的交互效果。其中,react-transition-group 是一个很棒的工具,它能让你轻松地为 React 应用添加动画效果。

今天,我们来聊聊如何在 React 18 和 React Router 6 中,使用 react-transition-group 实现路由切换动画。这不仅能让页面切换变得更平滑,还能让你的应用看起来更专业。

我们会从安装依赖开始,一步步设置路由和动画组件。然后,我会分享一些实用的小贴士和需要注意的地方,帮你避免常见的问题。希望这篇文章能为你带来一些启发,无论你是想提升应用的用户体验,还是对前端动画技术感兴趣,都不妨一试。

使用 react-transition-group 实现路由切换

在 React 应用中,实现路由切换动画可以带来更加平滑和流畅的用户体验。使用 react-transition-group,我们可以轻松地为路由切换添加动画效果,类似于 Vue 中的 transform 高阶组件。下面是一个详细的实现步骤和说明,帮助你使用 react-transition-group 实现路由切换动画。

  1. 安装依赖

首先,确保你的项目中已经安装了 react-router-dom 和 react-transition-group:

npm install react-router-dom react-transition-group
  1. 设置路由和动画组件

创建一个包含动画效果的组件,将其用于包裹 Outlet 组件。

注意: 不要直接使用 Outlet 及<Outlet />,而要使用useOutlet。

app.js 设置

import React from "react";
import { useLocation, useNavigate, useOutlet } from "react-router-dom";
import { CSSTransition, SwitchTransition } from "react-transition-group";
import "./index.scss";
function App(){
    const location = useLocation();
    const currentOutlet = useOutlet();
    return (
        <SwitchTransition mode="out-in">
          <CSSTransition
            key={location.pathname}
            appear={true}
            timeout={300}
            classNames="fade"
            unmountOnExit
          >
            {currentOutlet}
          </CSSTransition>
        </SwitchTransition>
);
}

app.js 中,使用 useOutlet 来获取当前的 outlet,并使用 SwitchTransitionCSSTransition 实现平滑的页面切换动画。通过 key 属性确保每次页面切换时的动画效果。

index.scss 设置动画效果

.fade-enter {
  opacity: 0;
}
.fade-enter-active {
  opacity: 1;
  transition: opacity 300ms;
}
.fade-exit {
  opacity: 1;
}
.fade-exit-active {
  opacity: 0;
  transition: opacity 300ms;
}
  1. 注意事项

总结和整理注意事项如下:

  1. 组件切换动画的实现

    1. 尽管许多文章建议使用 TransitionGroup 包裹所有路由,但官方建议在与 React Router 的更棘手组件(如 Redirect)一起使用时避免这种方法。因为这种方法需要一些 hack,并且容易崩溃。
    2. 推荐的做法是为每个路由使用 CSSTransition 并自行管理它们的 prop。
  2. 使用 SwitchTransition

    1. 使用 SwitchTransition 包裹 CSSTransition,这样可以避免页面上同时展示 A 页面和 B 页面的组件。
    2. 如果使用 TransitionGroup 包裹,会导致两个页面同时存在的情况。
  3. 使用 useOutlet ****而不是 <Outlet />

    1. 不要直接使用 Outlet<Outlet />,而是要使用 useOutlet

    2. 使用 SwitchTransitionCSSTransition<Outlet /> 包裹会导致以下问题:

      • 第一个页面的离开动画丢失。
      • 第二个页面会被加载两次,导致页面闪烁,useEffect(() => {}, []) 或者 componentDidMount() 被调用两次。
    3. 因为 <Outlet /> 会导致在同一页面的新旧组件各调用一次接口,所以请使用 useOutlet

相关链接

官方网站: reactcommunity.org/react-trans…

参考文章: www.cnblogs.com/inslog/p/18…

总结

在这篇文章中,我们详细介绍了如何在 React 18 和 React Router 6 中使用 react-transition-group 实现路由切换动画。通过安装必要的依赖并结合 useOutlet、SwitchTransition 和 CSSTransition,我们演示了如何为页面切换添加平滑的动画效果,并避免了直接使用 可能带来的问题。我们还讨论了 SwitchTransition 的优势,如何防止动画丢失和页面闪烁,帮助你提升用户体验。希望这些技巧能让你的应用看起来更专业、体验更流畅。