React中组件间过渡动画如何实现?

2023-10-27

一、是什么

在日常开发中,页面切换时的转场动画是比较基础的一个场景

当一个组件在显示与消失过程中存在过渡动画,可以很好的增加用户的体验

react中实现过渡动画效果会有很多种选择,如react-transition-groupreact-motionAnimated,以及原生的CSS都能完成切换动画

二、如何实现

react中,react-transition-group是一种很好的解决方案,其为元素添加enterenter-activeexitexit-active这一系列勾子

可以帮助我们方便的实现组件的入场和离场动画

其主要提供了三个主要的组件:

  • CSSTransition:在前端开发中,结合 CSS 来完成过渡动画效果
  • SwitchTransition:两个组件显示和隐藏切换时,使用该组件
  • TransitionGroup:将多个动画组件包裹在其中,一般用于列表中元素的动画

CSSTransition

其实现动画的原理在于,当CSSTransitionin属性置为true时,CSSTransition首先会给其子组件加上xxx-enterxxx-enter-activeclass执行动画

当动画执行结束后,会移除两个class,并且添加-enter-doneclass

所以可以利用这一点,通过csstransition属性,让元素在两个状态之间平滑过渡,从而得到相应的动画效果

in属性置为false时,CSSTransition会给子组件加上xxx-exitxxx-exit-activeclass,然后开始执行动画,当动画结束后,移除两个class,然后添加-enter-doneclass

如下例子:

export default class App2 extends React.PureComponent {

  state = {show: true};

  onToggle = () => this.setState({show: !this.state.show});

  render() {
    const {show} = this.state;
    return (
      <div className={'container'}>
        <div className={'square-wrapper'}>
          <CSSTransition
            in={show}
            timeout={500}
            classNames={'fade'}
            unmountOnExit={true}
          >
            <div className={'square'} />
          </CSSTransition>
        </div>
        <Button onClick={this.onToggle}>toggle</Button>
      </div>
    );
  }
}

对应css样式如下:

.fade-enter {
  opacity: 0;
  transform: translateX(100%);
}

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

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

.fade-exit-active {
  opacity: 0;
  transform: translateX(-100%);
  transition: all 500ms;
}

SwitchTransition

SwitchTransition可以完成两个组件之间切换的炫酷动画

比如有一个按钮需要在onoff之间切换,我们希望看到on先从左侧退出,off再从右侧进入

SwitchTransition中主要有一个属性mode,对应两个值:

  • in-out:表示新组件先进入,旧组件再移除;
  • out-in:表示就组件先移除,新组建再进入

SwitchTransition组件里面要有CSSTransition,不能直接包裹你想要切换的组件

里面的CSSTransition组件不再像以前那样接受in属性来判断元素是何种状态,取而代之的是key属性

下面给出一个按钮入场和出场的示例,如下:

import { SwitchTransition, CSSTransition } from "react-transition-group";

export default class SwitchAnimation extends PureComponent {
  constructor(props) {
    super(props);

    this.state = {
      isOn: true
    }
  }

  render() {
    const {isOn} = this.state;

    return (
      <SwitchTransition mode="out-in">
        <CSSTransition classNames="btn"
                       timeout={500}
                       key={isOn ? "on" : "off"}>
          {
          <button onClick={this.btnClick.bind(this)}>
            {isOn ? "on": "off"}
          </button>
        }
        </CSSTransition>
      </SwitchTransition>
    )
  }

  btnClick() {
    this.setState({isOn: !this.state.isOn})
  }
}

css文件对应如下:

.btn-enter {
  transform: translate(100%, 0);
  opacity: 0;
}

.btn-enter-active {
  transform: translate(0, 0);
  opacity: 1;
  transition: all 500ms;
}

.btn-exit {
  transform: translate(0, 0);
  opacity: 1;
}

.btn-exit-active {
  transform: translate(-100%, 0);
  opacity: 0;
  transition: all 500ms;
}

TransitionGroup

当有一组动画的时候,就可将这些CSSTransition放入到一个TransitionGroup中来完成动画

同样CSSTransition里面没有in属性,用到了key属性

TransitionGroup在感知children发生变化的时候,先保存移除的节点,当动画结束后才真正移除

其处理方式如下:

  • 插入的节点,先渲染dom,然后再做动画

  • 删除的节点,先做动画,然后再删除dom

如下:

import React, { PureComponent } from 'react'
import { CSSTransition, TransitionGroup } from 'react-transition-group';

export default class GroupAnimation extends PureComponent {
  constructor(props) {
    super(props);

    this.state = {
      friends: []
    }
  }

  render() {
    return (
      <div>
        <TransitionGroup>
          {
            this.state.friends.map((item, index) => {
              return (
                <CSSTransition classNames="friend" timeout={300} key={index}>
                  <div>{item}</div>
                </CSSTransition>
              )
            })
          }
        </TransitionGroup>
        <button onClick={e => this.addFriend()}>+friend</button>
      </div>
    )
  }

  addFriend() {
    this.setState({
      friends: [...this.state.friends, "coderwhy"]
    })
  }
}

对应css如下:

.friend-enter {
    transform: translate(100%, 0);
    opacity: 0;
}

.friend-enter-active {
    transform: translate(0, 0);
    opacity: 1;
    transition: all 500ms;
}

.friend-exit {
    transform: translate(0, 0);
    opacity: 1;
}

.friend-exit-active {
    transform: translate(-100%, 0);
    opacity: 0;
    transition: all 500ms;
}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

React中组件间过渡动画如何实现? 的相关文章

随机推荐

  • 充换电企业开迈斯低成本提升线上应用稳定性的最佳实践

    开迈斯新能源科技有限公司于 2019 年 5 月 16 日成立 目前合资股东分别为大众汽车 中国 投资有限公司 中国第一汽车股份有限公司 一汽 大众汽车有限公司 增资扩股将在取得适当监督 包括反垄断 审批后完成 万帮数字能源股份有限公司和安
  • 1.4秒到0.4秒-2行代码让JS加载耗时减少67%

    大厂技术 高级前端 Node进阶 点击上方 程序员成长指北 关注公众号 回复1 加入高级Node交流群 前言 大家好 我是考拉 资源优先级优化效果示例 png 仅需2行代码 就能实现上图中的优化效果 让JS文件的加载耗时从1 4秒减少到0
  • 七:微服务调用组件Feign

    目录 JAVA 项目中如何实现接口调用 1 什么是Feign 1 1 优势 1 2 Feign的设计架构 1 3 Ribbon Feign对比 1 4 Feign单独使用 2 Spring Cloud Alibaba快速整合Feign 3
  • 获取kafka队列中待消费Lag

    获取kafka中消费者某个topic主题待消费数据量 import java util ArrayList import java util HashMap import java util List import java util Ma
  • Invalid content was found starting with element ‘{“http://maven.apache.org/POM/4.0.0“:dependency}‘.

    在maven项目中运行时出现如下错误 点击上面的项目名 点击链接进入到报错的文件中 一般这种报错就是你的 Invalid content was found starting with element http maven apache o
  • java web项目中连接mysql数据库,javaweb之eclipse工程连接mysql数据库

    javaweb之eclipse工程连接mysql数据库 准备工作 1 在mysql官网下载mysqlconnection的jar包 输入网址 mysql com 点击DOWNLOADS 下拉选择MySQL Community GPL Dow
  • 入坑爬虫(六)某招聘网站信息采集

    前面的章节中 我们说到了如何发送发送 对应的 回顾之前的爬虫流程 在发送完请求之后 能够获取响应 这个时候就需要从响应中提取数据了 1 爬虫中数据的分类 在爬虫爬取到的数据中有很多不同类型的数据 我们需要了解数据的不同类型来规律的提取和解析
  • ADB简介

    Google官方网页 https developer android com studio command line adb html hl zh cn 对ADB的介绍在国内经常打不开 为了便于查看 这里从此网页中摘录了些经常使用到的内容
  • 2021杭电多校第三场-Road Discount-wqs二分+最小生成树

    Description There are n cities in Byteland labeled by 1 to n The Transport Construction Authority of Byteland is plannin
  • getLocation:fail Coordinate address resolution failed -1501

    这表示在获取位置信息时出现错误 具体原因可能是坐标地址解析失败 错误代码 1501 表示这种情况 你可以尝试重新请求位置信息 或者检查你的设备是否能够访问位置信息 例如 确保位置服务已打开
  • java swing实现文件浏览器功能小程序

    闲来无事学习了一下java的桌面应用开发组件Swing 做了个小程序 文件浏览器 只能查看信息不能进行过多操作 文件功能 查看指定文件路径下的所有文件夹和文件 可查看文件夹和文件的详细信息 切换不同排列方式等 基本逻辑 设置列表布局 添加数
  • Android 13 - Media框架(3)- MediaPlayer生命周期

    上一节了解了MediaPlayer api的使用 这一节就我们将会了解MediaPlayer的生命周期与api使用细节 1 MediaPlayer生命周期 MediaPlayer java 一开始有对生命周期的描述 这里对这些内容进行翻译
  • 服务器e4系列,Intel Xeon E系列服务器处理器

    一 Intel Xeon E系列CPU 命名规则 首先 Intel E3 E5 E7代表了3个不同档次的至强CPU 这种命名方式类似桌面上的Core i3 i5 i7 分别对应好 更好 最好 其次 以E3 1220为例 E3 1220中的这
  • RAR Extractor Mac:可以提取所有大多数格式的压缩文件

    RAR Extractor是mac上的解压缩软件 可以提取所有大多数格式 超过50种格式 的压缩文件 支持RAR winmAIl dat ZIP 7z tbz sti tar xar lha lzh hqx bin bz2 bzip2 bz
  • 保存登录的用户名

    自动测试服务器中用到用户的登录问题 在servlet中写上 String username request getParameter username 创建一个session对象 HttpSession session request ge
  • java 新手入门电子书_java从入门到精通第6版电子书 PDF高清版

    java从入门到精通第6版电子书 PDF高清版由软吧下载编辑精心整理 java从入门到精通第6版pdf是在之前的版本上更加详细的书籍 对于想要快速了解java的的话 欢迎下载java从入门到精通第6版pdf哦 欢迎下载使用 如果您觉得本站还
  • Java 初始化 List 的几种方法

    最常见的初始化 List 方法为 List
  • Flink,HDFS,YARN,Zookeeper之中的概念

    无论如何都要看一手资料 能看官方文档就不要看别的博客 有些地方很误导人 Hadoop内部子项目 HDFS YARN都是内部集成的 Hadoop Common The common utilities that support the oth
  • Java线程池中的线程发生OOM会如何?

    环境 JDK1 8 线程池中如果发生OOM后会如何 线程池ThreadPoolExecutor当有线程发生了OOM 线程池会停止工作吗 public static void main String args ThreadPoolExecut
  • React中组件间过渡动画如何实现?

    一 是什么 在日常开发中 页面切换时的转场动画是比较基础的一个场景 当一个组件在显示与消失过程中存在过渡动画 可以很好的增加用户的体验 在react中实现过渡动画效果会有很多种选择 如react transition group react