React中实现动画的两种方式及对比详解

 更新时间:2025年07月23日 10:31:30   作者:小飞悟  
在现代 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 状态变化定义动画的目标状态。当 isOpentrue 时,组件显示为不透明并回到原位置;为 false 时则隐藏。
  • transition: 定义动画过渡的持续时间(0.5 秒)和缓动函数(默认 ease),控制动画播放的节奏。
  • motion.div: 是 Framer Motion 提供的动画化组件,自动处理从初始状态到目标状态的插值与渲染过程。

2.4 优点与限制

特性说明
动画控制能力强支持延迟、循环、组合动画等高级动画逻辑
内置手势支持支持拖拽、点击、悬停等交互事件
性能优化良好基于 requestAnimationFrame,支持硬件加速
丰富的 API支持 TypeScript、React Hooks,生态完善
引入依赖需要引入第三方库,增加项目体积
学习成本略高需要一定时间学习其 API 和动画控制方式

三、CSS Transition 与 Framer Motion 对比总结

特性CSS TransitionFramer Motion
动画类型属性变化动画支持路径、物理模拟、组合动画
控制能力依赖类名和状态切换支持编程控制(暂停、重放、中断)
性能表现一般良好优化良好,支持硬件加速
学习成本中等
适用场景简单 UI 状态变化复杂交互动画、动效设计
依赖第三方库

四、使用选择建议

  • 简单 UI 动画(如按钮悬停、菜单展开):使用 CSS transition,轻量且易于实现。
  • 复杂交互动画(如模态框、页面切换、拖拽效果):使用 Framer Motion,其强大的控制能力和丰富的 API 能满足大多数复杂动画需求。
  • 混合使用:可以在项目中同时使用两者,CSS 负责基础动画,Framer Motion 负责高级动效。

到此这篇关于React中实现动画的两种方式及对比详解的文章就介绍到这了,更多相关React实现动画方式内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • React中Context的用法总结

    React中Context的用法总结

    Context 提供了一种在组件树中共享数据的方式,而不必通过 props 显式地逐层传递,主要用于共享那些对于组件树中许多组件来说是"全局"的数据,下面小编就来和大家简单讲讲Context的用法吧
    2025-01-01
  • ReactNative中使用Redux架构总结

    ReactNative中使用Redux架构总结

    本篇文章主要介绍了ReactNative中使用Redux架构总结,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-12-12
  • 关于React动态加载路由处理的相关问题

    关于React动态加载路由处理的相关问题

    这篇文章主要介绍了关于React动态加载路由处理的相关问题,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2019-01-01
  • React中使用echarts-for-react的方法示例

    React中使用echarts-for-react的方法示例

    echarts-for-react则是ECharts在React生态中的官方封装组件,它让开发者能够轻松地在React应用中集成ECharts图表,本文就来介绍一下echarts-for-react的使用,感兴趣的可以了解一下
    2025-03-03
  • ahooks useRequest源码精读解析

    ahooks useRequest源码精读解析

    这篇文章主要为大家介绍了ahooks useRequest的源码精读解析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-07-07
  • React antd中setFieldsValu的简便使用示例代码

    React antd中setFieldsValu的简便使用示例代码

    form.setFieldsValue是antd Form组件中的一个方法,用于动态设置表单字段的值,它接受一个对象作为参数,对象的键是表单字段的名称,值是要设置的字段值,这篇文章主要介绍了React antd中setFieldsValu的简便使用,需要的朋友可以参考下
    2023-08-08
  • React实现响应式布局的最佳实践

    React实现响应式布局的最佳实践

    在当今的前端开发中,响应式设计已经成为必不可少的部分,随着各种设备的出现,确保我们的网页在不同屏幕尺寸上展示良好,已经成为开发者的首要任务之一,本文将介绍如何在React中实现响应式布局,提供一些最佳实践和示例代码,帮助大家更好地理解这一概念
    2025-02-02
  • React createRef循环动态赋值ref问题

    React createRef循环动态赋值ref问题

    这篇文章主要介绍了React createRef循环动态赋值ref问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-01-01
  • React利用React.memo和useCallback缓存弹窗组件

    React利用React.memo和useCallback缓存弹窗组件

    本文主要介绍了React利用React.memo和useCallback缓存弹窗组件,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2025-07-07
  • 一文详解手动实现Recoil状态管理基本原理

    一文详解手动实现Recoil状态管理基本原理

    这篇文章主要为大家介绍了一文详解手动实现Recoil状态管理基本原理实例解析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-05-05

最新评论