React中如何为路由切换挂载的组件添加淡入动画?
给React Router路由组件添加淡入动画(无需大幅修改现有结构)
你的需求完全可行,而且不需要改动现有导航和路由的核心结构,下面是两种简单易实现的方案:
方案一:纯CSS + React Router路由监听
这种方法不需要额外依赖,只用原生React钩子和CSS就能实现:
1. 封装动画容器组件
在App.js里新增一个监听路由变化的容器组件,用来触发动画类:
import { BrowserRouter as Router, Routes, Route, NavLink, useLocation } from 'react-router-dom'; import { useEffect, useState } from 'react'; // 导入你的页面组件 import Home from './Home'; import About from './About'; import Contact from './Contact'; // 动画容器组件 const AnimatedRouteWrapper = ({ children }) => { const location = useLocation(); const [animate, setAnimate] = useState(false); // 路由变化时触发动画 useEffect(() => { setAnimate(true); // 动画时长和CSS保持一致 const timer = setTimeout(() => setAnimate(false), 300); return () => clearTimeout(timer); }, [location.pathname]); return ( <div className={`route-content ${animate ? 'fade-in' : ''}`}> {children} </div> ); }; function App() { return ( <Router> {/* 原有导航栏完全保留 */} <nav> <NavLink to="/" end>首页</NavLink> <NavLink to="/about">关于</NavLink> <NavLink to="/contact">联系</NavLink> </nav> {/* 用动画容器包裹路由 */} <AnimatedRouteWrapper> <Routes> <Route path="/" element={<Home />} /> <Route path="/about" element={<About />} /> <Route path="/contact" element={<Contact />} /> </Routes> </AnimatedRouteWrapper> </Router> ); } export default App;
2. 添加CSS动画样式
在全局CSS文件(比如index.css)里写过渡样式:
.route-content { opacity: 0; transition: opacity 0.3s ease-in-out; } .route-content.fade-in { opacity: 1; }
方案二:用React Transition Group实现更灵活的动画
如果需要更复杂的挂载/卸载动画(比如淡入+淡出切换),可以用react-transition-group库,同样不需要改动原有导航结构:
1. 安装依赖
npm install react-transition-group
2. 修改App.js代码
import { BrowserRouter as Router, Routes, Route, NavLink, useLocation } from 'react-router-dom'; import { TransitionGroup, CSSTransition } from 'react-transition-group'; // 导入你的页面组件 import Home from './Home'; import About from './About'; import Contact from './Contact'; function App() { const location = useLocation(); return ( <Router> {/* 原有导航栏不变 */} <nav> <NavLink to="/" end>首页</NavLink> <NavLink to="/about">关于</NavLink> <NavLink to="/contact">联系</NavLink> </nav> {/* 用TransitionGroup和CSSTransition包裹路由 */} <TransitionGroup> <CSSTransition key={location.pathname} timeout={300} classNames="fade" unmountOnExit > <Routes location={location}> <Route path="/" element={<Home />} /> <Route path="/about" element={<About />} /> <Route path="/contact" element={<Contact />} /> </Routes> </CSSTransition> </TransitionGroup> </Router> ); } export default App;
3. 添加对应CSS样式
/* 进入动画 */ .fade-enter { opacity: 0; } .fade-enter-active { opacity: 1; transition: opacity 0.3s ease-in-out; } /* 退出动画(可选) */ .fade-exit { opacity: 1; } .fade-exit-active { opacity: 0; transition: opacity 0.3s ease-in-out; }
两种方案都只需要在路由外层增加包裹组件,原有NavLink和路由配置完全不需要改动,直接复用即可。
内容的提问来源于stack exchange,提问作者Aniket Pandey
相关产品推荐
相关产品推荐

