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 庫。
入門指南
ReactCSSTransitionGroup 是 ReactTransitions 的接口。這是一個(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ì)粒度的控制,你可以使用底層的ReactTransitionGroupAPI,它提供了你自定義過渡效果所需要的掛鉤。
底層 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 官方文檔