UzumakiItachi
首页
  • JavaSript
  • Vue

    • Vue2
    • Vue3
  • React

    • React_18
  • WebPack
  • 浏览器相关
  • 工程化相关
  • 工作中遇到的问题以及解决方案
  • Git
  • 面试
  • 学习
  • 心情杂货
  • 实用技巧
  • 友情链接
关于
  • 个人产出
  • 实用工具
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

UzumakiItachi

起风了,唯有努力生存。
首页
  • JavaSript
  • Vue

    • Vue2
    • Vue3
  • React

    • React_18
  • WebPack
  • 浏览器相关
  • 工程化相关
  • 工作中遇到的问题以及解决方案
  • Git
  • 面试
  • 学习
  • 心情杂货
  • 实用技巧
  • 友情链接
关于
  • 个人产出
  • 实用工具
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • React三大基础Hook使用
  • 关于严格模式下useEffect执行两次的问题
  • 从零搭建一个React管理系统
  • useEffect闭包陷阱
  • react路由切换过度效果
    • 前言
    • 依赖安装
    • 包裹路由组件
    • css样式
    • 结语
  • React如何获取最新状态
  • 《React18》
hanhanbuku
2025-11-08
目录

react路由切换过度效果

# 前言

路由切换是项目中必备的一个东西,但原始的路由切换往往比较生硬,本文将通过react-transition-group包实现react-router的路由切换过度效果

# 依赖安装

npm install react-transition-group
1

使用上比较简单 通过react-transition-group库里的几个组件包裹住路由组件即可

# 包裹路由组件

由于本文使用的是react-router V7数据路由模式 所以并没有Routes,Route等组件,如果用的是低版本的路由则包裹Routes等组件即可,例子中是包裹子路由渲染出口Outlet组件

import { CSSTransition, SwitchTransition } from 'react-transition-group'
import {
    useNavigate,
    useLocation,
    useNavigation,
    useOutlet,
} from 'react-router-dom'
import {useRef} from 'react'

export const Layout  = ()=>{
    const curOutlet = useOutlet()
    const location = useLocation()
    const nodeRef = useRef(null)

    return (
        <>
            <SwitchTransition mode='out-in'>
                <CSSTransition
                    key={location.pathname}
                    timeout={500}
                    nodeRef={nodeRef}
                    classNames='fade'
                    unmountOnExit
                >
                    <div ref={nodeRef}>
                        <Suspense fallback={<LoadingFallback />}>
                            {curOutlet}
                        </Suspense>
                    </div>
                </CSSTransition>
            </SwitchTransition>
        </>
    )
}
const curOutlet = useOutlet()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36

然后定制一个css样式,以classNames的值命名

注意:这里样式不能写在cssModule里,因为cssModule会给样式添加上随机字符串,会导致react-transition-group无法正确的识别类名

# css样式


.fade-enter {
  opacity: 0;
  transform: translateX(-30px);
}

.fade-enter-active {
  opacity: 1;
  transform: translateX(0);
  transition: all 0.5s;
}

.fade-exit {
  opacity: 1;
  transform: translateX(0);
}

.fade-exit-active {
  opacity: 0;
  transform: translateX(30px);
  transition: all 0.5s;
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

这里我们把样式放在了index.css中,我们设置的类名是fade,react-transition-group会自动在fade后面拼上对应的过程名字

进入(enter)阶段:

  • enter: 进入开始状态(在进入动画开始前的一帧)
  • enter-active: 进入激活状态(整个进入动画过程)

退出(exit)阶段:

  • exit: 退出开始状态(在退出动画开始前的一帧)
  • exit-active: 退出激活状态(整个退出动画过程)

整体的使用就是这样,下面说几个注意事项:

  1. 为什么要使用useOutlet而不是直接使用<Outlet/>
    1. 使用SwitchTransition和 CSSTransition包裹<Outlet/>会导致离开动画失效,并且页面会闪烁
  2. 为什么要使用nodeRef
    1. 本文的实例使用了react19,react-transition-group使用了废弃的ReactDOM.findDOMNode,如果是react19以下版本可以忽略这个属性
  3. 为什么要使用Suspense包裹
    1. 因为组件时懒加载的,所以在切换路由的时候如果时间过长会出现白屏的问题,这里使用Suspense包裹住子路由的渲染出口可以防止整个页面白屏。

# 结语

以上就是react-transition-group的整体使用过程,注意几个事项即可

编辑 (opens new window)
上次更新: 2025/11/08, 11:20:23
useEffect闭包陷阱
React如何获取最新状态

← useEffect闭包陷阱 React如何获取最新状态→

最近更新
01
React如何获取最新状态
12-03
02
小程序实现全局状态管理
07-09
03
前端检测更新,自动刷新网页
06-09
更多文章>
Theme by Vdoing | Copyright © 2023-2025 UzumakiItachi | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式