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

如何在React Router路由切换时应用动画效果?

在React Router DOM中为路由切换添加动画效果

下面介绍两种常用的实现方式,适用于React Router DOM v6及以上版本:

方法一:纯CSS过渡动画

这种方式无需额外依赖,通过CSS过渡属性结合React Router的路由状态监听实现动画。

步骤1:设置路由容器与基础样式

在根组件中为路由添加容器,并定义CSS过渡规则:

// App.jsx
import { Routes, Route, useLocation } from 'react-router-dom';
import Home from './Home';
import About from './About';
import './RouteTransition.css';

function App() {
  const location = useLocation();

  return (
    <div className="route-container">
      {/* 给Routes添加key,确保路由切换时组件重新挂载 */}
      <Routes location={location} key={location.pathname}>
        <Route path="/" element={<Home />} />
        <Route path="/about" element={<About />} />
      </Routes>
    </div>
  );
}

export default App;
/* RouteTransition.css */
.route-container {
  position: relative;
  min-height: 100vh;
}

.route-component {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  opacity: 0;
  transform: translateX(20px);
  /* 定义过渡动画参数 */
  transition: opacity 0.3s ease, transform 0.3s ease;
}

.route-component.active {
  opacity: 1;
  transform: translateX(0);
}

步骤2:在路由组件中触发动画

在每个页面组件中,监听路由变化并切换激活类:

// Home.jsx
import { useEffect, useRef } from 'react';
import { useLocation } from 'react-router-dom';

function Home() {
  const location = useLocation();
  const componentRef = useRef(null);

  useEffect(() => {
    if (componentRef.current) {
      // 重置状态后强制重绘,确保动画触发
      componentRef.current.classList.remove('active');
      void componentRef.current.offsetWidth;
      componentRef.current.classList.add('active');
    }
  }, [location]);

  return (
    <div ref={componentRef} className="route-component">
      <h1>Home Page</h1>
    </div>
  );
}

export default Home;

方法二:使用Framer Motion实现复杂动画

Framer Motion是一个轻量的React动画库,能快速实现更丰富的路由切换效果。

步骤1:安装依赖

npm install framer-motion

步骤2:配置路由与动画

用<AnimatePresence>包裹路由,配合motion组件定义进入/退出动画:

// App.jsx
import { Routes, Route, useLocation } from 'react-router-dom';
import { AnimatePresence } from 'framer-motion';
import Home from './Home';
import About from './About';

function App() {
  const location = useLocation();

  return (
    {/* mode="wait" 确保旧组件退出动画完成后再加载新组件 */}
    <AnimatePresence mode="wait">
      <Routes location={location} key={location.pathname}>
        <Route path="/" element={<Home />} />
        <Route path="/about" element={<About />} />
      </Routes>
    </AnimatePresence>
  );
}

export default App;

步骤3:定义页面组件动画

在页面组件中使用motion.div并配置动画参数:

// Home.jsx
import { motion } from 'framer-motion';

// 定义动画状态
const pageVariants = {
  initial: { opacity: 0, x: 20 },
  animate: { opacity: 1, x: 0 },
  exit: { opacity: 0, x: -20 }
};

// 定义过渡属性
const pageTransition = {
  duration: 0.3,
  ease: "easeInOut"
};

function Home() {
  return (
    <motion.div
      variants={pageVariants}
      initial="initial"
      animate="animate"
      exit="exit"
      transition={pageTransition}
    >
      <h1>Home Page</h1>
    </motion.div>
  );
}

export default Home;

关键注意事项

  • 必须给<Routes>添加key={location.pathname},否则React不会重新渲染组件,动画无法触发。
  • 使用<AnimatePresence>时,确保路由组件支持exit动画(需要被motion组件包裹)。
  • 纯CSS方案中,void element.offsetWidth是强制浏览器重绘的技巧,避免动画不生效。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 22:55:48