在React中通過react-transition-group使用過渡、動畫,首先要有CSS3中的過渡和動畫的相關知識儲備,可以參考 過渡和2D變換、動畫和3d變換。
我們自己通過css設置過渡、動畫,需要給不同的class添加變化屬性,比如位移、縮放大小或者旋轉角度,再通過切換類名來達到動畫的效果,那么在react-transition-group當中,仍然需要在不同的class上定義不同的css樣式,簡化的是,不需要我們再來進行判斷切換類名,它規定了進入動畫、退出動畫分別的class后綴,我們只需要按照一定的規范去定義這些class即可。
可以看到class是有一個變化的過程的,當傳入屬性的值由true變成false時,即顯示到隱藏,class的變化過程為 enter enter-active 及enter-done,傳入屬性的值由false變成true時,及隱藏到顯示,class的變化過程為 exit exit-active和exit-done,知道react-transition-group的應用規律之后,再來看看它提供的主要API。
這樣第三方的庫,首先要做的事情就是安裝 npm i react-transition-group --save
最常用的是CSSTransition,它提供了與css相關的變化,它提供了一些屬性供我們使用
(1) in 傳入boolean值,傳入的是true代表開啟 enter enter-active和enter-done的這一變化過程,傳入false代碼開啟 exit exit-active exit-done這一過程 (必傳)
(2) timeout 表示執行時間,enter-active到enter-done 或者 exit-active到exit-done的執行時間 (必傳)
(3) classNames 定義添加的類名,這里定義的類名會被添加到 enter-xxx 及 exit-xxx 的之前
(4) ummountOnExit 默認為false,表示當傳入in的值為false值,CSSTransition中的元素不從dom中移除,傳true時則會被移除
可以看到class在 enter / exit之前都增加了一個自定義的class屬性box,以及當方塊消失的時候,方塊的dom元素被移除了,實現代碼如下
// jsx代碼 import React, { Component } from "react"; import { CSSTransition } from 'react-transition-group' import './style.css'; export default class CSSTransitionDemo extends Component { constructor(props){ super(props); this.state = { isShow: true } } render(){ const { isShow } = this.state; return( <div className="simpleTransition"> <button onClick={()=>this.setState({isShow:!isShow})}> 當前狀態:{isShow ? '顯示' : '隱藏'}</button> <CSSTransition in={isShow} classNames="box" timeout={1000} unmountOnExit={true}> <div className="helloBox"> hello </div> </CSSTransition> </div>) } } // css代碼 .box-enter { opacity: 0; transform: scale(0.6) } .box-enter-active { opacity: 1; transform: scale(1); transition: all 1000ms; } .box-exit { opacity: 1; transform: scale(1); } .box-exit-active { opacity: 0; transform: scale(.6); transition: all 1000ms }
(5) appear 定義首次加載的動畫, 同時需要在css中添加對應的類名和樣式, 可以與enter一致
(6) 動畫執行還有一些回調方法,需傳入函數,函數有一個入參,參數為CSSTransition所包裹的元素
onEnter、onEntering、onEntered、onExit、onExiting、onExited
實現代碼如下
// jsx <CSSTransition in={isShow} classNames="box" timeout={1000} unmountOnExit={true} appear onEnter={ el=>console.log('開始進入',el)} onEntering={ el => console.log('正在進入')} onEntered={ el => console.log('進入完成')} onExit={ el => console.log('開始退出')} onExiting={ el => console.log('正在退出')} onExited={ el => console.log('退出完成')}> // ... </CSSTransition> // css .box-enter, .box-appear { opacity: 0; transform: scale(0.6) } .box-enter-active, .box-appear-active { opacity: 1; transform: scale(1); transition: all 1000ms; }
實現代碼如下,需要CSSTransition配合使用,此時CSSTransition不需要定義in屬性,因為in屬性為false時就直接不展示整個元素了,此時需要定義不同的key來進行區分
// jsx <SwitchTransition mode="out-in"> <CSSTransition key={isShow ? 'on' : 'off'} classNames="btn" timeout={1000}> <button onClick={e=>this.setState({ isShow: !isShow })}> {isShow ? 'on' : 'off'} </button> </CSSTransition> </SwitchTransition> // css .btn-enter { opacity: 0; transform: translateX(100%) } .btn-enter-active { opacity: 1; transform: translateX(0); transition: opacity 1s, transform 1s } .btn-exit { opacity: 1; transform: translateX(0) } .btn-exit-active { opacity: 0; transform: translateX(-100%); transition: opacity 1s, transform 1s; }
實現代碼如下
<TransitionGroup> {this.state.movies.map((item, index)=>( <CSSTransition key={item.id} classNames="movie" timeout={1000}> <div>{item}</div> </CSSTransition> ))} <button onClick={e=>this.addMovies()}>添加電影</button> </TransitionGroup>
以上就是react-transition-group當中常用的三個組件,CSSTransition、SwitchTransition與TransitionGroup