react ReactCSSTransitionGroup 動(dòng)畫api

ReactCSSTransitionGroup

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

React 提供了一個(gè) ReactTransitionGroup 插件作為動(dòng)畫的底層API,和一個(gè) ReactCSSTransitionGroup 用于輕松實(shí)現(xiàn)基礎(chǔ)的CSS動(dòng)畫和過渡。

高級(jí) API: ReactCSSTransitionGroup

ReactCSSTransitionGroup 基于 ReactTransitionGroup 是一個(gè)當(dāng)React組件進(jìn)入或離開DOM時(shí),執(zhí)行CSS動(dòng)畫和過渡的簡單方法。它的靈感來自于杰出的 ng-animate 庫。

入門指南

ReactCSSTransitionGroupReactTransitions 的接口。這是一個(gè)簡單的元素,包裹了所有你感興趣的動(dòng)畫組件。這里是一個(gè)淡入和淡出列表項(xiàng)目的例子。

var ReactCSSTransitionGroup = require('react-addons-css-transition-group');

var TodoList = React.createClass({
  getInitialState: function() {
    return {items: ['hello', 'world', 'click', 'me']};
  },
  handleAdd: function() {
    var newItems =
      this.state.items.concat([prompt('Enter some text')]);
    this.setState({items: newItems});
  },
  handleRemove: function(i) {
    var newItems = this.state.items.slice();
    newItems.splice(i, 1);
    this.setState({items: newItems});
  },
  render: function() {
    var items = this.state.items.map(function(item, i) {
      return (
        <div key={item} onClick={this.handleRemove.bind(this, i)}>
          {item}
        </div>
      );
    }.bind(this));
    return (
      <div>
        <button onClick={this.handleAdd}>Add Item</button>
        <ReactCSSTransitionGroup transitionName="example" transitionEnterTimeout={500} transitionLeaveTimeout={300}>
          {items}
        </ReactCSSTransitionGroup>
      </div>
    );
  }
});

注意:

你必須為ReactCSSTransitionGroup的所有子級(jí)提供 key 屬性,即使只渲染一個(gè)項(xiàng)目。這就是React將決定哪一個(gè)子級(jí)進(jìn)入,離開,或者停留

在這個(gè)組件,當(dāng)一個(gè)新的項(xiàng)目被添加到 ReactCSSTransitionGroup ,他將得到example-enter CSS類 并且在下一刻example-enter-active CSS類被添加。這是一個(gè)基于transitionName prop 的約定。

你可以使用這些類來觸發(fā)CSS動(dòng)畫和過渡。比如,嘗試添加這個(gè)CSS和添加一個(gè)新的列表項(xiàng):

.example-enter {
  opacity: 0.01;
}

.example-enter.example-enter-active {
  opacity: 1;
  transition: opacity 500ms ease-in;
}

.example-leave {
  opacity: 1;
}

.example-leave.example-leave-active {
  opacity: 0.01;
  transition: opacity 300ms ease-in;
}

你會(huì)注意到動(dòng)畫持續(xù)時(shí)間需要被同時(shí)在CSS和渲染方法里被指定;這告訴React什么時(shí)候從元素中移除動(dòng)畫類,并且 -- 如果它正在離開 -- 何時(shí)從DOM移除元素。

讓初始化掛載動(dòng)畫

ReactCSSTransitionGroup 提供了可選的prop transitionAppear,來為在組件初始掛載添加一個(gè)額外的過渡階段。 通常在初始化掛載時(shí)沒有過渡階段因?yàn)?code>transitionAppear 的默認(rèn)值為false。下面是一個(gè)傳遞transitionAppear 為值true的例子。

  render: function() {
    return (
      <ReactCSSTransitionGroup transitionName="example" transitionAppear={true} transitionAppearTimeout={500}>
        <h1>Fading at Initial Mount</h1>
      </ReactCSSTransitionGroup>
    );
  }

在初始化掛載時(shí) ReactCSSTransitionGroup 將獲得example-appear CSS類 并且example-appear-active CSS 類在下一刻被添加。

.example-appear {
  opacity: 0.01;
}

.example-appear.example-appear-active {
  opacity: 1;
  transition: opacity .5s ease-in;
}

在初始化掛載,所有的 ReactCSSTransitionGroup 子級(jí)將會(huì) appear 但不 enter。然而,所有后來添加到已存在的 ReactCSSTransitionGroup 的子級(jí)將 enter 但不 appear。

注意:

prop transitionAppear 在版本 0.13 被添加到 ReactCSSTransitionGroup。為了保持向后兼容,默認(rèn)值被設(shè)置為 false。

制定類

可以為你的每一步過渡使用制定類名字。代理傳遞一個(gè)字符串到transitionName,你可以傳遞一個(gè)含有enter 或者leave 類名的對(duì)象,或者一個(gè)含有 enter, enter-active, leave-active, 和 leave 類名的對(duì)象。只要提供了enter 和 leave 的類,enter-active 和 leave-active 類會(huì)被決定為后綴'-active' 到類名的尾部。這里是兩個(gè)使用制定類的例子:

  ...
  <ReactCSSTransitionGroup
    transitionName={ {
      enter: 'enter',
      enterActive: 'enterActive',
      leave: 'leave',
      leaveActive: 'leaveActive',
      appear: 'appear',
      appearActive: 'appearActive'
    } }>
    {item}
  </ReactCSSTransitionGroup>

  <ReactCSSTransitionGroup
    transitionName={ {
      enter: 'enter',
      leave: 'leave',
      appear: 'appear'
    } }>
    {item2}
  </ReactCSSTransitionGroup>
  ...

動(dòng)畫組必須掛載才工作

為了使過渡效果應(yīng)用到子級(jí)上,ReactCSSTransitionGroup必須已經(jīng)掛載到了DOM或者 prop transitionAppear 必須被設(shè)置為 true。下面的例子不會(huì)工作,因?yàn)?ReactCSSTransitionGroup 隨同新項(xiàng)目被掛載,而不是新項(xiàng)目在它內(nèi)部被掛載。將這與上面的入門指南部分比較一下,看看不同。

  render: function() {
    var items = this.state.items.map(function(item, i) {
      return (
        <div key={item} onClick={this.handleRemove.bind(this, i)}>
          <ReactCSSTransitionGroup transitionName="example">
            {item}
          </ReactCSSTransitionGroup>
        </div>
      );
    }, this);
    return (
      <div>
        <button onClick={this.handleAdd}>Add Item</button>
        {items}
      </div>
    );
  }

動(dòng)畫一個(gè)或者零個(gè)項(xiàng)目 Animating One or Zero Items

在上面的例子中,我們渲染了一系列的項(xiàng)目到ReactCSSTransitionGroup里。然而 ReactCSSTransitionGroup 的子級(jí)同樣可以是一個(gè)或零個(gè)項(xiàng)目。這使它能夠動(dòng)畫化單個(gè)元素的進(jìn)入和離開。同樣,你可以動(dòng)畫化一個(gè)新的元素替換當(dāng)前元素。例如,我們可以像這樣實(shí)現(xiàn)一個(gè)簡單的圖片輪播器:

var ReactCSSTransitionGroup = require('react-addons-css-transition-group');

var ImageCarousel = React.createClass({
  propTypes: {
    imageSrc: React.PropTypes.string.isRequired
  },
  render: function() {
    return (
      <div>
        <ReactCSSTransitionGroup transitionName="carousel" transitionEnterTimeout={300} transitionLeaveTimeout={300}>
          <img src={this.props.imageSrc} key={this.props.imageSrc} />
        </ReactCSSTransitionGroup>
      </div>
    );
  }
});

禁用動(dòng)畫

如果你想,你可以禁用 enter 或者 leave 動(dòng)畫。例如,有時(shí)你可能想要一個(gè) enter 動(dòng)畫,不要 leave 動(dòng)畫,但是 ReactCSSTransitionGroup 會(huì)在移除你的DOM節(jié)點(diǎn)之前等待一個(gè)動(dòng)畫完成。你可以添加transitionEnter={false} 或者 transitionLeave={false} props 到 ReactCSSTransitionGroup 來禁用這些動(dòng)畫。

注意:

當(dāng)使用 ReactCSSTransitionGroup 時(shí),沒有辦法通知你的組件何時(shí)過渡效果結(jié)束或者在動(dòng)畫時(shí)執(zhí)行任何復(fù)雜的邏輯運(yùn)算。如果你想要更多細(xì)粒度的控制,你可以使用底層的 ReactTransitionGroup API,它提供了你自定義過渡效果所需要的掛鉤。

底層 API: ReactTransitionGroup

ReactTransitionGroup是動(dòng)畫的基礎(chǔ)。它通過 require('react-addons-transition-group') 訪問。當(dāng)子級(jí)被聲明式的從其中添加或移除(就像上面的例子)時(shí),特殊的生命周期掛鉤會(huì)在它們上面被調(diào)用。

componentWillAppear(callback)

對(duì)于被初始化掛載到 TransitionGroup 的組件,它和 componentDidMount() 在相同時(shí)間被調(diào)用 。它將會(huì)阻塞其它動(dòng)畫發(fā)生,直到callback被調(diào)用。它只會(huì)在 TransitionGroup 初始化渲染時(shí)被調(diào)用。

componentDidAppear()

在 傳給componentWillAppear回調(diào) 函數(shù)被調(diào)用后調(diào)用。

componentWillEnter(callback)

對(duì)于被添加到已存在的 TransitionGroup 的組件,它和 componentDidMount() 在相同時(shí)間被調(diào)用 。它將會(huì)阻塞其它動(dòng)畫發(fā)生,直到callback被調(diào)用。它不會(huì)在 TransitionGroup 初始化渲染時(shí)被調(diào)用。

componentDidEnter()

在傳給 componentWillEnter回調(diào)函數(shù)被調(diào)用之后調(diào)用。

componentWillLeave(callback)

在子級(jí)從 ReactTransitionGroup 中移除時(shí)調(diào)用。雖然子級(jí)被移除了,ReactTransitionGroup 將會(huì)保持它在DOM中,直到callback被調(diào)用。

componentDidLeave()

willLeave callback 被調(diào)用的時(shí)候調(diào)用(與 componentWillUnmount 同一時(shí)間)。

渲染一個(gè)不同的組件

默認(rèn)情況下 ReactTransitionGroup 渲染為一個(gè) span。你可以通過提供一個(gè) component prop 來改變這種行為。例如,下面是你將如何渲染一個(gè)<ul>

<ReactTransitionGroup component="ul">
  ...
</ReactTransitionGroup>

每一個(gè)React能渲染的DOM組件都是可用的。然而,組件不需要是一個(gè)DOM組件。它可以是任何你想要的React組件;甚至是你自己已經(jīng)寫好的!只要寫 component={List} 你的組件會(huì)收到 this.props.children

任何額外的、用戶定義的屬性將會(huì)成為已渲染的組件的屬性。例如,以下是你將如何渲染一個(gè)帶有css類的 <ul>

<ReactTransitionGroup component="ul" className="animated-list">
  ...
</ReactTransitionGroup>

此文摘自 react 官方文檔

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 179,351評(píng)論 25 708
  • It's a common pattern in React to wrap a component in an ...
    jplyue閱讀 3,411評(píng)論 0 2
  • 這篇筆記主要包含 Vue 2 不同于 Vue 1 或者特有的內(nèi)容,還有我對(duì)于 Vue 1.0 印象不深的內(nèi)容。關(guān)于...
    云之外閱讀 5,186評(píng)論 0 29
  • 南國千里疆、北望萬座山。 長槍所指、碟血戎裝。 蕩氣直問九宵。 天涯何處話、誰是英梟! 龍起卷、馬長嘶。 揮豪潑墨...
    戲夢(mèng)閱讀 542評(píng)論 5 4
  • 淡淡的淚閱讀 192評(píng)論 0 1

友情鏈接更多精彩內(nèi)容