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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 11:35:10