ReactCSSTransitionGroup
https://github.com/reactjs/react-transition-group
React 提供了一個 ReactTransitionGroup
插件作為動畫的底層API,和一個 ReactCSSTransitionGroup
用于輕松實現基礎的CSS動畫和過渡。
高級 API: ReactCSSTransitionGroup
ReactCSSTransitionGroup
基于 ReactTransitionGroup
是一個當React組件進入或離開DOM時,執行CSS動畫和過渡的簡單方法。它的靈感來自于杰出的 ng-animate 庫。
入門指南
ReactCSSTransitionGroup
是 ReactTransitions
的接口。這是一個簡單的元素,包裹了所有你感興趣的動畫組件。這里是一個淡入和淡出列表項目的例子。
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
的所有子級提供key
屬性,即使只渲染一個項目。這就是React將決定哪一個子級進入,離開,或者停留
在這個組件,當一個新的項目被添加到 ReactCSSTransitionGroup
,他將得到example-enter
CSS類 并且在下一刻example-enter-active
CSS類被添加。這是一個基于transitionName
prop 的約定。
你可以使用這些類來觸發CSS動畫和過渡。比如,嘗試添加這個CSS和添加一個新的列表項:
.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;
}
你會注意到動畫持續時間需要被同時在CSS和渲染方法里被指定;這告訴React什么時候從元素中移除動畫類,并且 -- 如果它正在離開 -- 何時從DOM移除元素。
讓初始化掛載動畫
ReactCSSTransitionGroup
提供了可選的prop transitionAppear
,來為在組件初始掛載添加一個額外的過渡階段。 通常在初始化掛載時沒有過渡階段因為transitionAppear
的默認值為false
。下面是一個傳遞transitionAppear
為值true
的例子。
render: function() {
return (
<ReactCSSTransitionGroup transitionName="example" transitionAppear={true} transitionAppearTimeout={500}>
<h1>Fading at Initial Mount</h1>
</ReactCSSTransitionGroup>
);
}
在初始化掛載時 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
子級將會 appear
但不 enter
。然而,所有后來添加到已存在的 ReactCSSTransitionGroup
的子級將 enter
但不 appear
。
注意:
prop
transitionAppear
在版本0.13
被添加到ReactCSSTransitionGroup
。為了保持向后兼容,默認值被設置為false
。
制定類
可以為你的每一步過渡使用制定類名字。代理傳遞一個字符串到transitionName,你可以傳遞一個含有enter
或者leave
類名的對象,或者一個含有 enter
, enter-active
, leave-active
, 和 leave
類名的對象。只要提供了enter 和 leave 的類,enter-active 和 leave-active 類會被決定為后綴'-active' 到類名的尾部。這里是兩個使用制定類的例子:
...
<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>
...
動畫組必須掛載才工作
為了使過渡效果應用到子級上,ReactCSSTransitionGroup
必須已經掛載到了DOM或者 prop transitionAppear
必須被設置為 true
。下面的例子不會工作,因為 ReactCSSTransitionGroup
隨同新項目被掛載,而不是新項目在它內部被掛載。將這與上面的入門指南部分比較一下,看看不同。
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>
);
}
動畫一個或者零個項目 Animating One or Zero Items
在上面的例子中,我們渲染了一系列的項目到ReactCSSTransitionGroup
里。然而 ReactCSSTransitionGroup
的子級同樣可以是一個或零個項目。這使它能夠動畫化單個元素的進入和離開。同樣,你可以動畫化一個新的元素替換當前元素。例如,我們可以像這樣實現一個簡單的圖片輪播器:
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>
);
}
});
禁用動畫
如果你想,你可以禁用 enter
或者 leave
動畫。例如,有時你可能想要一個 enter
動畫,不要 leave
動畫,但是 ReactCSSTransitionGroup
會在移除你的DOM節點之前等待一個動畫完成。你可以添加transitionEnter={false}
或者 transitionLeave={false}
props 到 ReactCSSTransitionGroup
來禁用這些動畫。
注意:
當使用
ReactCSSTransitionGroup
時,沒有辦法通知你的組件何時過渡效果結束或者在動畫時執行任何復雜的邏輯運算。如果你想要更多細粒度的控制,你可以使用底層的ReactTransitionGroup
API,它提供了你自定義過渡效果所需要的掛鉤。
底層 API: ReactTransitionGroup
ReactTransitionGroup
是動畫的基礎。它通過 require('react-addons-transition-group')
訪問。當子級被聲明式的從其中添加或移除(就像上面的例子)時,特殊的生命周期掛鉤會在它們上面被調用。
componentWillAppear(callback)
對于被初始化掛載到 TransitionGroup
的組件,它和 componentDidMount()
在相同時間被調用 。它將會阻塞其它動畫發生,直到callback
被調用。它只會在 TransitionGroup
初始化渲染時被調用。
componentDidAppear()
在 傳給componentWillAppear
的 回調
函數被調用后調用。
componentWillEnter(callback)
對于被添加到已存在的 TransitionGroup
的組件,它和 componentDidMount()
在相同時間被調用 。它將會阻塞其它動畫發生,直到callback
被調用。它不會在 TransitionGroup
初始化渲染時被調用。
componentDidEnter()
在傳給 componentWillEnter
的回調
函數被調用之后調用。
componentWillLeave(callback)
在子級從 ReactTransitionGroup
中移除時調用。雖然子級被移除了,ReactTransitionGroup
將會保持它在DOM中,直到callback
被調用。
componentDidLeave()
在willLeave
callback
被調用的時候調用(與 componentWillUnmount
同一時間)。
渲染一個不同的組件
默認情況下 ReactTransitionGroup
渲染為一個 span
。你可以通過提供一個 component
prop 來改變這種行為。例如,下面是你將如何渲染一個<ul>
:
<ReactTransitionGroup component="ul">
...
</ReactTransitionGroup>
每一個React能渲染的DOM組件都是可用的。然而,組件
不需要是一個DOM組件。它可以是任何你想要的React組件;甚至是你自己已經寫好的!只要寫 component={List}
你的組件會收到 this.props.children
任何額外的、用戶定義的屬性將會成為已渲染的組件的屬性。例如,以下是你將如何渲染一個帶有css類的 <ul>
:
<ReactTransitionGroup component="ul" className="animated-list">
...
</ReactTransitionGroup>
此文摘自 react 官方文檔