You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Router v6.4.1中使用AnimatePresence实现页面退出动画的问题

React Router v6.4.1 中 Framer Motion 退出动画失效的解决方法

React Router v6.4 引入的createBrowserRouter和RouterProvider新API,会导致外层包裹的AnimatePresence无法触发页面退出动画——因为RouterProvider是稳定的根组件,路由切换时它不会卸载,AnimatePresence监听不到页面组件的卸载动作,自然无法执行退出动画。

解决思路

把AnimatePresence移到路由内部,配合Outlet使用,让路由切换时触发包裹页面的容器组件重新挂载,从而让AnimatePresence检测到组件的卸载与挂载,执行对应的动画。

具体实现步骤

  1. 创建动画布局组件
    这个组件会用AnimatePresence包裹Outlet,并通过当前路由的pathname作为key,确保路由切换时容器重新渲染:

    import { Outlet, useLocation } from 'react-router-dom';
    import { AnimatePresence } from 'framer-motion';
    
    const AnimatedLayout = () => {
      const location = useLocation();
    
      return (
        <AnimatePresence mode="wait">
          <div key={location.pathname}>
            <Outlet />
          </div>
        </AnimatePresence>
      );
    };
    
    export default AnimatedLayout;
    
  2. 配置路由结构
    将动画布局作为父路由的element,页面路由作为子路由嵌套其中:

    import { createBrowserRouter, RouterProvider } from 'react-router-dom';
    import AnimatedLayout from './AnimatedLayout';
    import HomePage from './HomePage';
    import AboutPage from './AboutPage';
    
    const router = createBrowserRouter([
      {
        path: '/',
        element: <AnimatedLayout />,
        children: [
          { index: true, element: <HomePage /> },
          { path: 'about', element: <AboutPage /> },
        ],
      },
    ]);
    
    function App() {
      return <RouterProvider router={router} />;
    }
    
    export default App;
    
  3. 给页面组件添加动画属性
    每个页面组件必须用motion组件包裹,并配置initial、animate、exit动画参数:

    import { motion } from 'framer-motion';
    
    const HomePage = () => {
      return (
        <motion.div
          initial={{ opacity: 0, y: 20 }}
          animate={{ opacity: 1, y: 0 }}
          exit={{ opacity: 0, y: -20 }}
          transition={{ duration: 0.4 }}
        >
          <h1>首页</h1>
          <p>这是首页内容</p>
        </motion.div>
      );
    };
    
    export default HomePage;
    

关键说明

  • mode="wait"会让AnimatePresence等待当前页面的退出动画完成后,再渲染新页面,避免动画重叠。
  • 必须为每个页面组件配置exit属性,否则AnimatePresence不会触发退出动画。
  • 用location.pathname作为容器的key,是为了让路由切换时触发容器的重新挂载,让AnimatePresence识别到组件的变化。

内容的提问来源于stack exchange,提问作者TSTobias

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 08:25:13