如何在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
相关产品推荐
相关产品推荐

