likes
comments
collection
share

React动画:react-transition-group 使用以及动画原理

作者站长头像
站长
· 阅读数 42

简单介绍

React Transition Group 是一个 React 库,用于管理和处理在 React 应用中的过渡动画效果。它提供了一组组件,可以帮助你在组件的进入和退出时应用动画效果。

这个动画库在npm上周下载量高达 1200 多万:npm

React动画:react-transition-group 使用以及动画原理

我自己对它的理解是一个轻量、简单的动画库,它甚至不算一个动画库,它只提供触发机制、具体动画需要自行编写,它可以应对大量常见简单动画,如果你需要编写高级动画,建议用react-springframer-motion等。

它主要包含四个组件TransitionCSSTransitionSwitchTransitionTransitionGroup 这四个组件,本文主要以CSSTransition进行讲解。

CSSTransition

CSSTransition是我们最常用的一个组件,它提供两组动画的切换,一般我们可以用于元素的隐藏和显示,可以应对大部分的简单动画,相比于我们手动去添加类名等操作,它会更加方便。

基本使用:

我们需要用CSSTransition组件来包裹需要做动画的元素,并且只能有一个children元素。

正确写法✅✅✅

<CSSTransition in={show} timeout={2000} classNames="fade">
	<div className=“box”></div>
</CSSTransition>

错误写法❌❌❌

<CSSTransition in={show} timeout={2000} classNames="fade">
	<div className=“box”></div>
  <div className=“box”></div>
</CSSTransition>

并且,CSSTransition这个元素最终并不会渲染到页面中,只会留下box元素。

再讲讲CSSTransition组件常用的属性:

  • in:用于动画的切换,boolean 值,分别对应进入和退出两组动画
    • false -> true: 对应一组动画类名:*-enter、 *-enter-active、 *-enter-done
    • true-> false:对应一组动画类名:*-exit、 *-exit-active、 *-exit-done
  • timeout:动画的作用时间,单位:ms
  • classNames:两种形式,字符串形式:指定动画类名的前缀对象形式:指定每一个具体的类名
  • unmountOnExit:元素在完成动画时是否从页面中移除该dom元素
  • appear:指定元素首次渲染在页面时,是否进行动画。对应一组动画类名:*-appear、 *-appear-active、 *-appear-done

这边代码演示环境:

先来写一个最简单的示例,点击切换显示隐藏,使用 transform 和 opacity。

import React, { useState } from "react";
import styles from "./styles.module.scss";
import { CSSTransition, SwitchTransition } from "react-transition-group";
import { Button } from "antd";

const AnimationExample: React.FC = () => {
  const [show, setShow] = useState(true);

  return (
    <div className={styles.app}>
      <div className={styles.handle}>
        <Button type="primary" onClick={() => setShow(!show)}>
          切换
        </Button>
      </div>

      <CSSTransition
        in={show}
        timeout={500}
        classNames={{
          enter: styles.fadeEnter,
          enterActive: styles.fadeEnterActive,
          enterDone: styles.fadeEnterDone,
          exit: styles.fadeExit,
          exitActive: styles.fadeExitActive,
          exitDone: styles.fadeExitDone,
        }}
      >
        <div className={styles.box}></div>
      </CSSTransition>
    </div>
  );
};

export default AnimationExample;
.box {
  width: 100px;
  height: 100px;
  background-color: orange;
  border-radius: 24px;
}

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

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

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

.fade-exit-active {
  opacity: 0;
  transform: translateX(100%);
  transition: all 0.5s;
}
.fade-exit-done {
  opacity: 0;
  transform: translateX(100%);
  transition: all 0.5s;
}

因为我这里使用了 css modules,并开启了类名自动转小驼峰,才是这种写法,也可以使用类名前缀写法(我这里指定了fade前缀),使用全局样式。

<CSSTransition in={show} timeout={500} classNames="fade">
    <div className={styles.box}></div>
</CSSTransition>

效果如下:

React动画:react-transition-group 使用以及动画原理

简单分析过程:

初始时,我们设置intrue,我们点击切换,intrue -> false

  • 先后.box元素添加.fade-exit.fade-exit-active类名,元素根据类名开始做动画,并开始计时(timeout)。
  • timeout时间到,移除.fade-exit.fade-exit-active这两个类名,并添加.fade-exit-done类名,过程结束。

我们再次点击切换,infalse -> true

  • 移除.fade-exit-done,并先后添加.fade-enter.fade-enter-active,元素开始做动画,并开始计时(timeout)。
  • timeout时间到,移除.fade-enter.fade-enter-active,并添加.fade-enter-done。过程结束。

简单总结,CSSTransition 的动画原理就是在指定时刻添加添加类名和移除类名,通过 transition css属性达成平滑过渡,它并没有使用到 @keyframes

思考:timeout 到底是什么时间?

这个 api 挺疑惑的,是动画持续时间?NO!我们的动画时间已经在css中指定了:transition: all 0.5s;。这个timeout准确来说应该是*-enter*-enter-active(或者*-exit和 *-exit-active)的作用时间

我们从添加类名开始计时,timeout一到,就移除*-enter*-enter-active,并添加*-enter-done

我们把动画放慢,可以清晰观察元素的状态

React动画:react-transition-group 使用以及动画原理

unmountOnExit

unmountOnexit属性用于当我们 intrue -> false 动画结束后,是否从页面中移除该dom元素,默认为false,我们上面的例子可以看到是没有移除dom元素,我只是改变了透明度。

当我们设置为true后,当 in 从 true -> false时,dom元素会从页面中移除,当 false -> true时,dom元素会被重新创建添加到指定位置。

<CSSTransition in={show} timeout={2000} classNames="fade" unmountOnExit={true}>
    <div className={styles.box}></div>
</CSSTransition>

React动画:react-transition-group 使用以及动画原理

appear

我们尝试刷新一下浏览器,模拟一次页面初始化,每个dom第一次创建并挂载到页面上,发现这个dom元素并不会进行动画,如果我们想在 dom元素初次渲染就进行一次动画,可以使用appear这个属性,并且在相关类名添加*-appear*-appear-active*-appear-enter

<CSSTransition in={show} timeout={2000} classNames="fade" appear={true}>
		<div className={styles.box}></div>
</CSSTransition>
.fade-appear {
  opacity: 0;
  transform: translateX(100%);
}

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

我们可以对比两个效果。

React动画:react-transition-group 使用以及动画原理

React动画:react-transition-group 使用以及动画原理

钩子函数

CSSTransition还提供一组动画函数,用于在指定时刻进行调用,参数如下:

  • el:进行过渡动画的 DOM 节点
  • isAppearing:组件是否是首次出现(如果设置了 appear 属性)。

其中,onEnter、onEntering、onEntered提供两个参数:el、isAppearing

onExit、onExiting、onExited提供一个参数:el

      <CSSTransition
        in={show}
        timeout={2000}
        classNames="fade"
        appear={true}
        onEnter={(el, isAppearing) => console.log(el, isAppearing, "开始进入")}
        onEntering={(el, isAppearing) => console.log("正在进入")}
        onEntered={(el, isAppearing) => console.log("进入完成")}
        onExit={(el) => console.log("开始退出")}
        onExiting={(el) => console.log("正在退出")}
        onExited={(el) => console.log("退出完成")}
      >

文章到此就结束了,相信理解了 CSSTransition 的原理,SwitchTransitionTransitionGroup 你也能轻松驾驭。

最后,创作不易,希望可以点个赞支持一下🥰🥰,若文章出现错误,还请指出。

转载自:https://juejin.cn/post/7251033389998456892
评论
请登录