react中使用動畫 react-transition-group


在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,再來說說 SwitchTransition,SwitchTransition的作用就是切換展示的內容,有兩種模式,分別是先隱藏舊內容再展示新的內容(out-in),先展示新內容再展示舊內容(in-out)

 

實現代碼如下,需要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;
}

還有一個是GroupTransition,用來給CSSTransition分組,當通過遍歷來給元素添加 CSSTransition的動畫時,需要再最外層增加 GroupTransition 才能添加上動畫

實現代碼如下

<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遍歷數據時是希望我們加上唯一的key值,一方面是因為dom的diff算法進行比較時能夠提高性能,另一方面,有時候沒有key值會出現一些錯誤,比如像以下情況,逆序刪除元素的時候,刪除的是第一個元素,但是卻給最后一個元素添加了動畫

以上就是react-transition-group當中常用的三個組件,CSSTransition、SwitchTransition與TransitionGroup


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM