五、React过渡动画实现

135 阅读3分钟

一、React的过渡动画

1. react-transition-group介绍

  • 开发中,给一个组件的显示和消失添加某种过渡动画,可以很好的增加用户体验
  • 可以通过原生css来实现这些过渡动画,但react社区已经提供了react-transition-group用来完成过渡动画
  • react曾提供动画插件 react-addons-transition-group,后来由社区维护,成为现在的react-transition-group
    • 这个库可以帮助我们方便的实现组件的入场和离场动画,使用时需要进行额外的安装
      • npm install react-transition-group --save
      • yarn add react-transition-group
  • react-transition-group本身非常小,不会为我们的应用程序增加过多的负担

2. react-transition-group主要组件

  • react-transition-group主要包含四个组件
  • Transition
    • 该组件是一个和平台无关的组件(不一定要结合CSS)
    • 开发中,一般是结合css来完成样式,所以常用的是CSSTransition
  • CSSTransition
    • 完成过渡动画效果
  • SwitchTransition
    • 两个组件显示和隐藏切换时,使用该组件
  • TransitionGroup
    • 将多个动画组件包裹在其中,一般用于列表中的元素的动画

二、CssTransition使用

CssTransition

  • CSSTransition是基于Transition组件构建的
  • CSSTransition执行过程中,有三个状态:appear、enter、exit
  • 三种状态,需要定义对应的CSS样式
    • 第一类,开始状态:对应的类是 -appear、-enter、exit
    • 第二类,执行动画:对应的类是 -appear-active、-enter-active、-exit-active
    • 第三类:执行结束:对应的类是 -appear-done、-enter-done、-exit-done
  • CSSTransition常见对应的属性
  • in:触发进入或退出状态
    • 如果添加了 unmountOnExit={true},那么该组件会在执行退出动画结束后被移除掉
    • 当 in 为true时,触发进入状态,会添加-enter、-enter-active的calss开始执行动画,当动画执行结束后,会移除两个class,并且添加-enter-done的class
    • 当 in 为false时,触发退出状态,会添加-exit、-exit-active的class开始执行动画,当动画执行结束后,会移除两个class,并且添加 -exit-done的class

三、常见的属性设置

CSSTransition常见属性

  • classNames:动画class的名称
    • 决定了在编写css时,对应的class名称:如card-enter、card-enter-active、card-enter-done
  • timeout:
    • 过渡动画的时间
  • appear:
    • 是否在初次进入添加动画(需要和in同时为true)
  • unmountOnExit:退出后卸载组件
  • 其它属性官网:reactcommunity.org/react-trans…
  • CSSTransition对应的钩子函数:主要为了检测动画的执行过程,来完成一些JavaScript的操作
    • onEnter:在进入动画之前被触发
    • onEntering:在应用进入动画时被触发
    • onEntered:在应用进入动画结束后被触发
    • onExit:开始离开动画
    • onExiting:执行离开动画
    • onExited:执行离开结束
/* 进入动画 */
.fade-enter {
    opacity: 0;
}
.fade-enter-active {
    transition: opacity 1s;
    opacity: 1;
}

/* 离开动画 */
.fade-exit {
    opacity: 1;
}
.fade-exit-active {
    transition: opacity 1s;
    opacity: 0;
}
.fade-exit-done {
    opacity: 0;
}
  • react-transition-group底层使用了过期的api findDOMNode;所以要想在严格模式中使用,应该采用如下获取DOM的方式
import React, { PureComponent, createRef } from 'react'

import { CSSTransition } from 'react-transition-group'

export class TransitionP extends PureComponent {
    constructor(props) {
        super()
        this.state = {
            show: true
        }
        this.fadeRef=createRef()
    }
    render() {
        const { show } = this.state
        return (
        <div>
            <button onClick={e => this.setState({ show: !show })}>button</button>
            <CSSTransition 
                nodeRef={this.fadeRef}
                in={show} 
                timeout={2000} 
                classNames="fade"
                unmountOnExit={true}
            >
                <div ref={this.fadeRef}>
                    <h2>title</h2>
                    <p>CSSTransition</p>
                </div>
            </CSSTransition>
        </div>
        )
    }
}

export default TransitionP

四、SwitchTransition

SwitchTransition

  • SwitchTransition可以完成两个组件之间切换的炫酷动画
    • 如一个按钮需要在 on 和 off 之间切换,我们希望看到 on 先从左侧退出,off 再从右侧进入
    • 这个动画在vue中被称为 vue transition modes
    • react-transition-group中使用SwitchTransition来实现该动画
  • SwitchTransition中主要有一个属性:mode,有两个值
    • in-out:表示新组件先进入,旧组件再移除
    • out-in:表示旧组件先移除,新组件再进入
  • 如何使用?
    • SwitchTransition组件里面要有CSSTransition或者transition组件,不能直接包裹切换的组件
    • SwitchTransition里面的CSSTransition或Transition组件不再像以前那样接受 in 属性来判断元素是何种状态,取而代之的是key属性

五、TransitionGroup

TransitionGroup

  • 当有一组动画时,需要将这些CSSTransition放入到一个TransitionGroup中来完成动画