一、插件
React.addons是为了构建 React应用而放置的一些有用工具的地方。此功能应当被视为实验性的,但最终将会被添加进核心代码中或者有用的工具库中:
TransitionGroup和CSSTransitionGroup,用于处理动画和过渡,这些通常实现起来都不简单,例如在一个组件移除之前执行一段动画。
LinkedStateMixin,用于简化用户表单输入数据和组件 state之间的双向数据绑定。
classSet,用于更加干净简洁地操作 DOM中的 class字符串。
cloneWithProps,用于实现 React组件浅复制,同时改变它们的 props。
update,一个辅助方法,使得在 JavaScript中处理不可变数据更加容易。
PureRenderMixin,在某些场景下的性能检测器。
以下插件只存在于 React开发版(未压缩):
TestUtils,简单的辅助工具,用于编写测试用例(仅存在于未压缩版).
Perf,用于性能测评,并帮助你检查出可优化的功能点。
要使用这些插件,需要用react-with-addons.js(和它的最小化副本)替换常规的React.js。
当通过npm使用react包的时候,只要简单地用 require('react/addons') 替换 require('react')来得到带有所有插件的React。
二、动画
React为动画提供了一个ReactTransitionGroup插件组件作为一个底层的API,一个ReactCSSTrasitionGroup来简单的实现基本的CSS动画和过渡。
高级API:ReactCSSTransitionGroup
ReactCSSTransitionGroup是基于ReactTransitionGroup的,在React组件进入或者离开DOM的时候,它是一种简单地执行CSS过渡和动画的方式。这个的灵感来自于优秀的ng-animate库。
ReactCSSTransitionGroup是ReactTransitions的接口。这是一个简单的元素,包含了所有你对其动画感兴趣的组件。这里是一个例子,例子中我们让列表项淡入淡出:
‘
var ReactCSSTransitionGroup =React.addons.CSSTransitionGroup;
var TodoList =React.createClass({
getInitialState: function() {
return {items: ['hello', 'world', 'click','me']};
},
handleAdd: function() {
var newItems =
this.state.items.concat([prompt('Entersome text')]);
this.setState({items: newItems});
},
handleRemove: function(i) {
var newItems = this.state.items;
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>
<buttononClick={this.handleAdd}>Add Item</button>
<ReactCSSTransitionGrouptransitionName="example">
{items}
</ReactCSSTransitionGroup>
</div>
);
}
});
PS:你必须为ReactCSSTransitionGroup的所有子级提供键属性,即使只渲染一项。这就是?React确定哪一个子级插入了,移除了,或者停留在那里。
在这个组建里,当一个心啊的项被添加到ReactCSSTransitionGroup,他将会添加example-enter类,然后下一时刻被添加example-enter-active CSS类。这是一个给予transitionNameProp的约定。
可以是哦能给这些类出发一个CSS动画或者过渡,例如,尝试添加这段CSS代码,然后插入一个新的列表项:
.example-enter {
opacity: 0.01;
transition: opacity .5s ease-in;
}
.example-enter.example-enter-active{
opacity: 1;
}
你可以注意到当你尝试一处一项的时候,ReactCSSTransitionGroup保持这项在DOM里。如果你正使用一个带有插件的未压缩的React构建版本,你将会看到一条警告,React期待一次动火或者过度发生,那是因为ReactCSSTransitionGroup保持你的DOM元素一直在页面上,知道动画完成,尝试添加下面这段CSS代码:
.example-leave {
opacity: 1;
transition: opacity .5s ease-in;
}
.example-leave.example-leave-active{
opacity: 0.01;
}
一组动画必须要挂载了才可以生效:
为了能过给它的子级应用过渡效果,ReactCSSTransitionGroup必须已经挂载到饿了DOM,下面的例子不会生效,因为ReactCSSTransitionGroup
被挂在到先新项,而不是新项被挂载到ReactCSSTransitionGroup里。
render: function() {
var items =this.state.items.map(function(item, i) {
return (
<div key={item}onClick={this.handleRemove.bind(this, i)}>
<ReactCSSTransitionGrouptransitionName="example">
{item}
</ReactCSSTransitionGroup>
</div>
);
}, this);
return (
<div>
<buttononClick={this.handleAdd}>Add Item</button>
{items}
</div>
);
}
让一项或者零项动起来(AnimatingOne or Zero Items)
虽然在上面的例子中,我们渲染了一个项目列表到ReactCSSTransitionGroup里,ReactCSSTransitionGroup的子级可以是一个或零个项目。这使它能够让一个元素实现进入和离开的动画。同样,你可以通过移动一个新的元素来替换当前元素。随着新元素的移入,当前元素移出。例如,我们可以由此实现一个简单的图片轮播器:
varReactCSSTransitionGroup = React.addons.CSSTransitionGroup;
var ImageCarousel =React.createClass({
propTypes: {
imageSrc: React.PropTypes.string.isRequired
},
render: function() {
return (
<div>
<ReactCSSTransitionGrouptransitionName="carousel">
<img src={this.props.imageSrc}key={this.props.imageSrc} />
</ReactCSSTransitionGroup>
</div>
);
}
});
禁用动画
如果你想,你可以禁用入场或者出场动画。例如,有些时候,你可能想要一个入场动画,不要出场动画,但是ReactCSSTransitionGroup会在移除DOM节点之前等待一个动画完成。你可以给ReactCSSTransitionGroup添加transitionEnter={false}或者transitionLeave={false} props来禁用这些动画.
注意:
当使用ReactCSSTransitionGroup的时候,没有办法通知你在过渡效果结束或者在执行动画的时候做一些复杂的运算。如果你想要更多细粒度的控制,你可以使用底层的ReactTransitionGroup API,该API提供了你自定义过渡效果所需要的函数。
底层的API:ReactTransitionGroup
ReactTransitionGroup是动画的基础。它可以通过React.addons.TransitionGroup得到。当子级被添加或者从其中移除(就像上面的例子)的时候,特殊的生命周期函数就会在它们上面被调用。
componentWillEnter(callback)
在组件被添加到已有的TransitionGroup中的时候,该函数和componentDidMount()被同时调用。这将会阻塞其它动画触发,直到callback被调用。该函数不会在TransitionGroup初始化渲染的时候调用。
componentDidEnter()
该函数在传给componentWillEnter的callback函数被调用之后调用。
componentWillLeave(callback)
该函数在子级从ReactTransitionGroup中移除的时候调用。虽然子级被移除了,ReactTransitionGroup将会使它继续在DOM中,直到callback被调用。
componentDidLeave()
该函数在willLeave callback被调用的时候调用(与componentWillUnmount是同一时间)。
渲染一个不同的组件
默认情况下ReactTransitionGroup渲染一个span。你可以通过提供一个component prop来改变这种行为。例如,以下是你将如何渲染一个<ul>:
<ReactTransitionGroup component="ul">
...
</ReactTransitionGroup>
每一个React能渲染的DOM组件都是可用的。但是,组件并不需要是一个DOM组件。它可以是任何你想要的React组件;甚至是你自己已经写好的!
注意:
v0.12之前,当使用DOM组件的时候,组件 prop需要是一个指向React.DOM.*的引用。既然组件简单地传递到了React.createElement,它必须是一个字符串。组装的组件必须传递构造函数。
任何额外的、用户定义的属性将会成为已渲染的组件的属性。例如,以下是你将如何渲染一个带有css类的<ul>:
<ReactTransitionGroup component="ul" className="animated-list">
...
</ReactTransitionGroup>