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

如何在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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 03:56:26