使用react-transition-group实现动画

github: https://github.com/reactjs/react-transition-group

说明文档: https://reactcommunity.org/react-transition-group/

#先安装
yarn add react-transition-group

这里着重讲一下CSSTransition

CSSTransition通过一个bool值能自动感知到状态的变化,然后自动帮你往CSSTransition包裹的元素上动态添加和删除class

属性分析:

  • in:传给CSSTransition的bool值
  • timeout:时间
  • classNames:动画className前缀
  • unmountOnExit: 退出时,移除元素
  • appear:bool, 网页第一次展示的时候,是否也执行动画

钩子函数

  • onEnter:入场动画第一帧,会执行
  • onEntering: 'enter-active' or 'appear-active' 2个class挂载完之后会执行
  • onEntered:当入场动画结束之后,会执行
  • onExit:出场动画第一帧,会执行
  • onExiting:当'exit-active' class被挂载完会执行
  • onExited: 当出场动画结束之后,会执行

动画结束添加颜色

方法1

app.js

import React, { Component, Fragment } from 'react';
import './index.css';
import { CSSTransition } from 'react-transition-group';
//CSSTransition会自动帮我们做一些样式的添加和删除工作

class App extends Component{
    constructor(props){
        super(props)
        this.state={
            show:true
        }
        this.handleToggle = this.handleToggle.bind(this)
    }
    render(){
        return (
            <Fragment>
                <CSSTransition
                    in={this.state.show}
                    timeout={1000}
                    classNames="fade"
                    unmountOnExit
                >
                    <div>hello world</div>
                </CSSTransition>
                 <button onClick={this.handleToggle}>toggle</button>
            </Fragment>
        )
    }

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

export default App;

index.css

.fade-enter{
    opacity: 0;
}

.fade-enter-active{
    opacity: 1;
    transition: opacity 1s ease-in;
}

.fade-enter-done{
    opacity: 1;
    color: red;
}

.fade-exit{
    opacity: 1;
}

.fade-exit-active{
    opacity: 0;
    transition: opacity 1s ease-in;
}

.fade-exit-done{
    opacity: 0;
}

方法二:钩子函数

app.js

import React, { Component, Fragment } from 'react';
import './index.css';
import { CSSTransition } from 'react-transition-group';
//CSSTransition会自动帮我们做一些样式的添加和删除工作

class App extends Component{
    constructor(props){
        super(props)
        this.state={
            show:true
        }
        this.handleToggle = this.handleToggle.bind(this)
    }
    render(){
        return (
            <Fragment>
                <CSSTransition
                    in={this.state.show}
                    timeout={1000}
                    classNames="fade"
                    unmountOnExit
                    onEntered = {(el)=>{el.style.color='blue'}}
                >
                    <div>hello world</div>
                </CSSTransition>
                 <button onClick={this.handleToggle}>toggle</button>
            </Fragment>
        )
    }

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

export default App;

index.css

.fade-enter, .fade-appear{
    opacity: 0;
}

.fade-enter-active, .fade-appear-active{
    opacity: 1;
    transition: opacity 1s ease-in;
}

.fade-enter-done{
    opacity: 1;
}

.fade-exit{
    opacity: 1;
}

.fade-exit-active{
    opacity: 0;
    transition: opacity 1s ease-in;
}

.fade-exit-done{
    opacity: 0;
}

一组动画的实现

TransitionGroup是更低层的组件,如果CSSTransition实现不了,可以用TransitionGroup app.js

import React, { Component, Fragment } from 'react';
import './index.css';
import { CSSTransition, TransitionGroup } from 'react-transition-group';
//CSSTransition会自动帮我们做一些样式的添加和删除工作

class App extends Component{
    constructor(props){
        super(props)
        this.state={
            list:[]
        }
        this.handleAddItem = this.handleAddItem.bind(this)
    }
    render(){
        return (
            <Fragment>
                <TransitionGroup>
                {
                    this.state.list.map((item,index)=>{
                        return (
                                <CSSTransition
                                    timeout={1000}
                                    classNames="fade"
                                    unmountOnExit
                                    onEntered = {(el)=>{el.style.color='blue'}}
                                    appear = {true}
                                    key = {index}
                                >
                                    <div>{item}</div>
                                </CSSTransition>
                        )
                    })
                }     
                 </TransitionGroup>
                 <button onClick={this.handleAddItem}>Add Item</button>
            </Fragment>
        )
    }

    handleAddItem(){
        this.setState((prevState)=>{
            return {
                list:[...prevState.list,'item']
            }

        })
    }
}

export default App;

index.css

.fade-enter, .fade-appear{
    opacity: 0;
}

.fade-enter-active, .fade-appear-active{
    opacity: 1;
    transition: opacity 1s ease-in;
}

.fade-enter-done{
    opacity: 1;
}

.fade-exit{
    opacity: 1;
}

.fade-exit-active{
    opacity: 0;
    transition: opacity 1s ease-in;
}

.fade-exit-done{
    opacity: 0;
}