如何在React路由中设置延迟函数及实现页面过渡类操作?
React路由过渡与延迟函数的实现方案
嘿,我来一步步拆解你这些问题,都是React开发里关于路由过渡的常见需求,咱们一个个来解决:
一、React中如何设置延迟函数?
其实React里的延迟函数和原生JS没差,直接用setTimeout就行,但一定要记得清理定时器,避免组件卸载后定时器还在运行导致内存泄漏。
函数组件示例:
import { useEffect } from 'react'; function MyComponent() { useEffect(() => { const timer = setTimeout(() => { console.log('1秒后执行的逻辑'); // 这里可以放修改状态、触发动画之类的操作 }, 1000); // 组件卸载时清除定时器 return () => clearTimeout(timer); }, []); return <div>示例组件</div>; }
如果是类组件,就在componentWillUnmount生命周期里清除定时器就行。
二、路由切换时动态增删/切换类实现过渡
要实现路由切换时的类操作,核心是监听路由变化,然后通过状态控制组件的类名,配合CSS过渡动画。我们可以用react-router-dom的useLocation钩子来监听路由变化。
手动控制类的基础示例
import React, { useState, useEffect } from "react"; import { BrowserRouter as Router, Route, Link, useLocation } from "react-router-dom"; // 封装一个过渡容器组件,复用过渡逻辑 const RouteTransitionWrapper = ({ children }) => { const location = useLocation(); const [isTransitioning, setIsTransitioning] = useState(false); const [currentPath, setCurrentPath] = useState(location.pathname); useEffect(() => { // 路由变化时,先标记为过渡中,触发退出动画 setIsTransitioning(true); // 等待动画时长后,更新当前路径并结束过渡,触发进入动画 const timer = setTimeout(() => { setCurrentPath(location.pathname); setIsTransitioning(false); }, 500); // 这个时间要和CSS过渡时长一致 return () => clearTimeout(timer); }, [location]); return ( <div className={`page-container ${isTransitioning ? 'transition-out' : 'transition-in'}`} > {/* 只有路径匹配时才渲染内容,避免过渡时新旧内容重叠 */} {currentPath === location.pathname && children} </div> ); }; // 页面组件 const Home = () => <h2>Home</h2>; const About = () => <h2>About</h2>; const Contact = () => <h2>Contact</h2>; const BasicExample = () => ( <Router> <div> <ul> <li><Link to="/">Home</Link></li> <li><Link to="/about">About</Link></li> <li><Link to="/contact">Contact</Link></li> </ul> {/* 给每个路由页面套上过渡容器 */} <Route path="/" exact> <RouteTransitionWrapper><Home /></RouteTransitionWrapper> </Route> <Route path="/about"> <RouteTransitionWrapper><About /></RouteTransitionWrapper> </Route> <Route path="/contact"> <RouteTransitionWrapper><Contact /></RouteTransitionWrapper> </Route> </div> </Router> ); export default BasicExample;
对应的CSS样式:
.page-container { transition: all 0.5s ease; } .transition-out { opacity: 0; transform: translateX(-20px); } .transition-in { opacity: 1; transform: translateX(0); }
三、结合延迟函数实现类的增删/切换
上面的示例其实已经把setTimeout和类操作结合起来了:路由变化时先添加transition-out类触发退出动画,延迟500ms(和CSS动画时长一致)后,切换到transition-in类并更新页面内容,完成整个过渡流程。
如果需要更精细的控制(比如先完全退出旧页面,再加载新页面),可以调整定时器逻辑:
// 修改RouteTransitionWrapper里的useEffect useEffect(() => { setIsTransitioning(true); // 先等退出动画完成 const exitTimer = setTimeout(() => { setCurrentPath(location.pathname); // 再等100ms后结束过渡,触发进入动画 const enterTimer = setTimeout(() => { setIsTransitioning(false); }, 100); return () => clearTimeout(enterTimer); }, 500); return () => clearTimeout(exitTimer); }, [location]);
四、使用第三方库简化实现
如果不想手动写定时器和类控制,推荐用**react-transition-group**,这是React官方推荐的过渡动画库,和react-router配合非常丝滑。
步骤1:安装依赖
npm install react-transition-group
步骤2:编写代码
import React from "react"; import { BrowserRouter as Router, Route, Link, useLocation } from "react-router-dom"; import { CSSTransition, TransitionGroup } from "react-transition-group"; const Home = () => <h2>Home</h2>; const About = () => <h2>About</h2>; const Contact = () => <h2>Contact</h2>; const BasicExample = () => { const location = useLocation(); return ( <Router> <div> <ul> <li><Link to="/">Home</Link></li> <li><Link to="/about">About</Link></li> <li><Link to="/contact">Contact</Link></li> </ul> {/* TransitionGroup管理过渡组件,CSSTransition自动处理类名 */} <TransitionGroup> <CSSTransition key={location.key} // 用路由的key来触发过渡 timeout={500} classNames="page-transition" // 类名前缀,自动生成enter/exit相关类 > {/* 用location属性确保路由匹配正确 */} <Route location={location} path="/" exact> <Home /> </Route> <Route location={location} path="/about"> <About /> </Route> <Route location={location} path="/contact"> <Contact /> </Route> </CSSTransition> </TransitionGroup> </div> </Router> ); }; export default BasicExample;
对应的CSS:
/* 进入动画初始状态 */ .page-transition-enter { opacity: 0; transform: translateX(20px); } /* 进入动画执行状态 */ .page-transition-enter-active { opacity: 1; transform: translateX(0); transition: all 0.5s ease; } /* 退出动画初始状态 */ .page-transition-exit { opacity: 1; transform: translateX(0); } /* 退出动画执行状态 */ .page-transition-exit-active { opacity: 0; transform: translateX(-20px); transition: all 0.5s ease; }
这个库会自动帮你处理类的添加、移除和定时器,不需要手动写setTimeout,大大简化了代码。
内容的提问来源于stack exchange,提问作者MD.ALIMUL Alrazy
相关产品推荐
相关产品推荐

