React中实现动画的两种方式及对比详解
作者:小飞悟
在现代 Web 开发中,动画不仅是提升用户体验的重要手段,更是增强用户交互、引导用户行为、提升界面美感的关键因素,本文将通过两个例子,讲解一下如何在 React 中使用 CSS transition 和 Framer Motion 实现动画,并对比它们的优缺点,需要的朋友可以参考下
引言
在现代 Web 开发中,动画不仅是提升用户体验的重要手段,更是增强用户交互、引导用户行为、提升界面美感的关键因素。React 本身不直接提供动画功能,但通过 CSS 的 transition 和第三方动画库如 Framer Motion,我们可以轻松实现丰富的动画效果。
本文将通过两个例子,讲解一下如何在 React 中使用 CSS transition 和 Framer Motion 实现动画,并对比它们的优缺点,帮助我们在项目中做出合适的技术选型。
一、使用 CSS transition 实现动画
1.1 示例代码解析
我们先来看一个简单的动画组件,实现一个点击按钮后展开/收起的盒子效果。
// Box.jsx
import styles from './box.module.styl';
import { useState } from 'react';
const Box = () => {
const [open, setOpen] = useState(false);
return (
<div>
<button onClick={() => setOpen(!open)}>
{open ? 'Close' : 'Open'}
</button>
<div className={`${styles.box} ${open ? styles.open : ''}`}></div>
</div>
);
};
export default Box;
对应的 box.module.styl 文件(使用 Stylus):
.box
width: 100px
height: 0
background-color: lightblue
transition: height 0.3s ease
overflow: hidden
.box.open
height: 100px
动画展示:

1.2 工作原理
.box初始高度为0。- 当点击按钮时,
open状态改变,组件的类名变为.box.open。 .box.open的高度变为100px,通过transition属性,高度变化会以 0.3 秒的动画形式完成。
1.3 优点与限制
| 特性 | 说明 |
|---|---|
| 简单易用 | 适用于简单的属性变化动画,如颜色、大小、位置等 |
| 性能良好 | 浏览器对 CSS 动画进行了优化 |
| 无需依赖 | 不需要引入额外库 |
| 控制力弱 | 难以实现复杂动画逻辑 |
| 状态管理繁琐 | 需要手动管理类名和状态切换 |
二、使用 Framer Motion 实现动画
2.1 安装 Framer Motion
在使用 Framer Motion 之前,需要先安装它。小编使用的是pnpm,可以使用以下命令安装:
pnpm install framer-motion
安装完成后,我们就可以在 React 组件中导入 motion 组件并开始使用它了。
2.2 示例代码解析
下面是一个使用 Framer Motion 实现的动画组件,展示点击按钮后内容从上方向下淡入的动画效果:
// MotionBox.jsx
import { motion } from 'framer-motion'
import { useState } from 'react'
const MotionBox = () => {
const [isOpen, setIsOpen] = useState(false)
return (
<div>
<button onClick={() => setIsOpen(!isOpen)}>
{isOpen ? '隐藏内容' : '显示内容'}
</button>
<motion.div
initial={{ opacity: 0, y: -50 }}
animate={{ opacity: isOpen ? 1 : 0, y: isOpen ? 0 : -50 }}
transition={{ duration: 0.5 }}
style={{
backgroundColor: 'skyblue',
padding: 20,
marginTop: 10,
pointerEvents: 'none' // 防止动画区域被误点
}}
>
<h2>Motion Box</h2>
<p>这是一个使用 Framer Motion 的动画组件</p>
</motion.div>
</div>
)
}
export default MotionBox
动画展示

2.3 工作原理
initial: 定义组件初始状态,如透明度为 0,垂直方向向上偏移 50px。animate: 根据isOpen状态变化定义动画的目标状态。当isOpen为true时,组件显示为不透明并回到原位置;为false时则隐藏。transition: 定义动画过渡的持续时间(0.5 秒)和缓动函数(默认ease),控制动画播放的节奏。motion.div: 是 Framer Motion 提供的动画化组件,自动处理从初始状态到目标状态的插值与渲染过程。
2.4 优点与限制
| 特性 | 说明 |
|---|---|
| 动画控制能力强 | 支持延迟、循环、组合动画等高级动画逻辑 |
| 内置手势支持 | 支持拖拽、点击、悬停等交互事件 |
| 性能优化良好 | 基于 requestAnimationFrame,支持硬件加速 |
| 丰富的 API | 支持 TypeScript、React Hooks,生态完善 |
| 引入依赖 | 需要引入第三方库,增加项目体积 |
| 学习成本略高 | 需要一定时间学习其 API 和动画控制方式 |
三、CSS Transition 与 Framer Motion 对比总结
| 特性 | CSS Transition | Framer Motion |
|---|---|---|
| 动画类型 | 属性变化动画 | 支持路径、物理模拟、组合动画 |
| 控制能力 | 依赖类名和状态切换 | 支持编程控制(暂停、重放、中断) |
| 性能表现 | 一般良好 | 优化良好,支持硬件加速 |
| 学习成本 | 低 | 中等 |
| 适用场景 | 简单 UI 状态变化 | 复杂交互动画、动效设计 |
| 依赖 | 无 | 第三方库 |
四、使用选择建议
- 简单 UI 动画(如按钮悬停、菜单展开):使用 CSS
transition,轻量且易于实现。 - 复杂交互动画(如模态框、页面切换、拖拽效果):使用 Framer Motion,其强大的控制能力和丰富的 API 能满足大多数复杂动画需求。
- 混合使用:可以在项目中同时使用两者,CSS 负责基础动画,Framer Motion 负责高级动效。
到此这篇关于React中实现动画的两种方式及对比详解的文章就介绍到这了,更多相关React实现动画方式内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
