ReactCSSTransitionGroup
https://github.com/reactjs/react-transition-group
React 提供了一個(gè) ReactTransitionGroup
插件作為動(dòng)畫(huà)的底層API,和一個(gè) ReactCSSTransitionGroup
用于輕松實(shí)現(xiàn)基礎(chǔ)的CSS動(dòng)畫(huà)和過(guò)渡。
高級(jí) API: ReactCSSTransitionGroup
ReactCSSTransitionGroup
基于 ReactTransitionGroup
是一個(gè)當(dāng)React組件進(jìn)入或離開(kāi)DOM時(shí),執(zhí)行CSS動(dòng)畫(huà)和過(guò)渡的簡(jiǎn)單方法崩哩。它的靈感來(lái)自于杰出的 ng-animate 庫(kù)赛糟。
入門指南
ReactCSSTransitionGroup
是 ReactTransitions
的接口洛搀。這是一個(gè)簡(jiǎn)單的元素倘潜,包裹了所有你感興趣的動(dòng)畫(huà)組件格遭。這里是一個(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)入栖袋,離開(kāi),或者停留
在這個(gè)組件抚太,當(dāng)一個(gè)新的項(xiàng)目被添加到 ReactCSSTransitionGroup
,他將得到example-enter
CSS類 并且在下一刻example-enter-active
CSS類被添加塘幅。這是一個(gè)基于transitionName
prop 的約定。
你可以使用這些類來(lái)觸發(fā)CSS動(dòng)畫(huà)和過(guò)渡尿贫。比如电媳,嘗試添加這個(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)畫(huà)持續(xù)時(shí)間需要被同時(shí)在CSS和渲染方法里被指定;這告訴React什么時(shí)候從元素中移除動(dòng)畫(huà)類,并且 -- 如果它正在離開(kāi) -- 何時(shí)從DOM移除元素庆亡。
讓初始化掛載動(dòng)畫(huà)
ReactCSSTransitionGroup
提供了可選的prop transitionAppear
匾乓,來(lái)為在組件初始掛載添加一個(gè)額外的過(guò)渡階段。 通常在初始化掛載時(shí)沒(méi)有過(guò)渡階段因?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
咧七。然而衰齐,所有后來(lái)添加到已存在的 ReactCSSTransitionGroup
的子級(jí)將 enter
但不 appear
。
注意:
prop
transitionAppear
在版本0.13
被添加到ReactCSSTransitionGroup
继阻。為了保持向后兼容耻涛,默認(rèn)值被設(shè)置為false
。
制定類
可以為你的每一步過(guò)渡使用制定類名字瘟檩。代理傳遞一個(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)畫(huà)組必須掛載才工作
為了使過(guò)渡效果應(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)畫(huà)一個(gè)或者零個(gè)項(xiàng)目 Animating One or Zero Items
在上面的例子中,我們渲染了一系列的項(xiàng)目到ReactCSSTransitionGroup
里柜某。然而 ReactCSSTransitionGroup
的子級(jí)同樣可以是一個(gè)或零個(gè)項(xiàng)目嗽元。這使它能夠動(dòng)畫(huà)化單個(gè)元素的進(jìn)入和離開(kāi)。同樣喂击,你可以動(dòng)畫(huà)化一個(gè)新的元素替換當(dāng)前元素剂癌。例如,我們可以像這樣實(shí)現(xiàn)一個(gè)簡(jiǎn)單的圖片輪播器:
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)畫(huà)
如果你想,你可以禁用 enter
或者 leave
動(dòng)畫(huà)翰绊。例如佩谷,有時(shí)你可能想要一個(gè) enter
動(dòng)畫(huà),不要 leave
動(dòng)畫(huà)监嗜,但是 ReactCSSTransitionGroup
會(huì)在移除你的DOM節(jié)點(diǎn)之前等待一個(gè)動(dòng)畫(huà)完成谐檀。你可以添加transitionEnter={false}
或者 transitionLeave={false}
props 到 ReactCSSTransitionGroup
來(lái)禁用這些動(dòng)畫(huà)。
注意:
當(dāng)使用
ReactCSSTransitionGroup
時(shí)裁奇,沒(méi)有辦法通知你的組件何時(shí)過(guò)渡效果結(jié)束或者在動(dòng)畫(huà)時(shí)執(zhí)行任何復(fù)雜的邏輯運(yùn)算桐猬。如果你想要更多細(xì)粒度的控制,你可以使用底層的ReactTransitionGroup
API刽肠,它提供了你自定義過(guò)渡效果所需要的掛鉤溃肪。
底層 API: ReactTransitionGroup
ReactTransitionGroup
是動(dòng)畫(huà)的基礎(chǔ)免胃。它通過(guò) require('react-addons-transition-group')
訪問(wèn)。當(dāng)子級(jí)被聲明式的從其中添加或移除(就像上面的例子)時(shí)惫撰,特殊的生命周期掛鉤會(huì)在它們上面被調(diào)用羔沙。
componentWillAppear(callback)
對(duì)于被初始化掛載到 TransitionGroup
的組件,它和 componentDidMount()
在相同時(shí)間被調(diào)用 润绎。它將會(huì)阻塞其它動(dòng)畫(huà)發(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)畫(huà)發(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
造烁。你可以通過(guò)提供一個(gè) component
prop 來(lái)改變這種行為。例如午笛,下面是你將如何渲染一個(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 官方文檔