用react-transition-group实现动画

在react中,我们主要使用react-transition-group实现动画过度效果,本文将讨论如何在react项目中实现过度动画效果。

安装

# npm
npm install react-transition-group --save

# yarn
yarn add react-transition-group

官方提供的三个组建Transition,CSSTransition,TransitonGroup

使用

1.Transition

过渡组件(Transiton)允许您用一个简单的声明性API描述随着时间的推移从一个组件状态到另一个组件状态的转换。最常用的是用来动画一个组件的安装和卸载,但也可以用来描述在适当的过渡状态。默认情况下,该组件不会更改其呈现的组件的行为,它只跟踪组件的“进入”和“退出”的状态。由你来为这些状态定义效果。

//自己简单的封装了一个,该有的参数都由了,可以自行粘贴在自己的代码里面去试试。
class Fade extends React.Component {
  constructor(props) {
    super(props);
  }
  done =() => {
    // console.log('结束了')
  }
  addaddEndListener = (node) => { //原生时间transition运动的事件
    node.addEventListener('transitionend', this.done, false);
  }

  // 三个进入状态的事件,可以做你想做的事情
  onEnter = (node, isAppearing) => {
    console.log(isAppearing, 'onEnter')
  }
  onEntering = (node, isAppearing) => {
    console.log(isAppearing, 'onEntering')
  }
  onEntered = (node, isAppearing) => {
    console.log(isAppearing, 'onEntered')
  }

  // 三个退出的状态的事件
  onExit = (node) => {
    console.log('onExit')
  }
  onExiting = () => {
    console.log('onExiting')
  }
  onExited = () => {
    console.log('onExited')
    this.props.self()
  }
  render() {
    const { in: inProp, dur} = this.props;
    const defaultStyle = {
      transition: `transform ${300}ms ease-in-out, opacity ${300}ms ease-in-out`,
      transform: 'translateX(100px)',
      opacity: '0'
    }

    const transitionStyles = {
      entering: { transform: 'translateX(100px)', opacity: '0'},
      entered:  { transform: 'translateX(0px)', opacity: '1' },
      exiting: {transform: 'translateX(0px)', opacity: '1'},
      exited: {transform: 'translateX(0px)', opacity: '0'}
    };
    const duration = {
      enter: 300,
      exit: 300,
    }
    // 上面的都是基本参数,样式的转变以及时间的设定,具体的可以看官网文档
    // 样式也可以写成className 例如<MyComponent className={`fade fade-${status}`} />
    return (
      <Transition 
        onEnter={this.onEnter}
        onEntering={this.onEntering}
        onEntered={this.onEntered}

        onExit={this.onExit}
        onExiting={this.onExiting}
        onExited={this.onExited}

        addEndListener={this.addaddEndListener} 
        in={inProp} 
        unmountOnExit={false} // 为true 代表退出的时候移除dom
        appear={true} // 为true  渲染的时候就直接执行动画,默认false,
        timeout={duration}
      >
        {
          state => {
            console.log(state, '###') //你可以很直观的看到组件加载和卸载时候的状态
            return(
              <div style={{
                ...defaultStyle,
                ...transitionStyles[state]
              }}>
                {this.props.children}
              </div>
            )
          }
        }
      </Transition>
    );
  }
}

Transition组件本身不会对其子组件执行任何操作。它所做的是跟踪一段时间内的转换状态,以便在更改状态时更新组件(例如通过添加样式或类)。

Transition可以有4种主要状态:

entering
entered
exiting
exited
//组件的初始化状态都停留在exited

调用方法:

let num = 1;
class Dnd extends React.Component {
  state = {
    ins: true,
    current: 1,
    dom: <div className={l.test}>
            ceshi weizhi {num}
          </div>
  }
  handle = (bool) => {
    this.setState({
      test: !bool
    })
  }
  end = () => {
    const that = this;
    num = num + 1;
    setTimeout(function () {
      that.setState({
        test: true,
        dom: <div className={l.test}>
              888888 {num}
            </div>
      }) 
    }, 500)
    
  }
  render () {
    const { location } = this.props
    const { test } = this.state;
    return (
      <MainLayout location={location}>
        <Button onClick={this.handle.bind(null, this.state.test)}>点击transition</Button>
        <Fade in={this.state.test} self={this.end}>
          {this.state.dom}
        </Fade>
      </MainLayout>
    )
  }
}
// 效果是每次点击按钮都会进行一次进场和出场的动画。也可以自行衍生。

2.CSSTransition

class Example extends Component{
    state={
        isShow:true
    }
    render(){
        return (
            <div>
               <h2>CSSTransition</h2>
               <CSSTransition
                    in={this.state.isShow}
                    classNames="message"
                    unmountOnExit//是否占茅坑
                    timeout={5000}//消失延迟
                    appear = {true}
               >
                    {
                        <div className="box">看我秀你一脸狗屎</div>
                    } 
               </CSSTransition>
               <p><button onClick= {() => this.setState({isShow: !this.state.isShow})}>toggle</button></p>
            </div>
        )
    }
}

相对应的钩子函数如下:

classNames={{
 appear: 'my-appear',
 appearActive: 'my-active-appear',
 enter: 'my-enter',
 enterActive: 'my-active-enter',
 enterDone: 'my-done-enter,
 exit: 'my-exit',
 exitActive: 'my-active-exit',
 exitDone: 'my-done-exit,
}}

附相关css:



.message-enter, .message-appear {
    opacity: 0;
    /* transform: scale(0.9) translateY(50%); */
  }
  .message-enter-active, .message-appear-active {
    opacity: 1;
    /* transform: scale(1) translateY(0%); */
    transition: all 1000ms ease-out;
  }
  .message-enter-done {
    opacity: 1;
  }
  .message-exit {
    opacity: 1;
    /* transform: scale(1) translateY(0%); */
  }
  .message-exit-active {
    opacity: 0.01;
    /* transform: scale(0.9) translateY(50%); */
    transition: all 1000ms ease-out;
  }
  .message-exit-done {
    opacity: 0;
    /* transform: scale(1) translateY(0%); */
  }

3.TransitionGroup

class Example extends Component{
    state = {
        isShow: true,
        items: [
            {id: uuid(), text: 'Hello World'},
            {id: uuid(), text: 'Hello React'},
        ]
    }
    render () {
        return (
            <div>
                <TransitionGroup>
                    {
                        this.state.items.map(item => (
                            <CSSTransition
                                key = {item.id}
                                timeout = {1000}
                                classNames = "message"
                                unmountOnExit
                                
                            >
                                {
                                    (state) => (<h3 >{item.text} -- {state}</h3>)
                                }
                            </CSSTransition>
                        ))
                    }
                </TransitionGroup>
            
                <p><button onClick= {() => {
                    this.setState({
                        items: [ ...this.state.items, {
                            id: uuid(), text: 'new Hello'
                        }]
                    })
                }}>add</button></p>

            </div>
        )
    }
}

(css同第二部分)

请注意,<TransitionGroup> 没有定义任何动画行为!究竟如何列表项动画是由个人<Transition> 组成部分。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值