React Addons Animation

Animation

React 提供一个ReactTransitionGroup扩展组件作为动画的低级接口,和一个ReactCSSTransitionGroup用于轻松实现基于CSS的动画和转换效果。

高级别接口:ReactCSSTransitionGroup

ReactCSSTransitionGroup是基于ReactTransitionGroup的,它是一个当React组件进入或离开DOM的时候执行CSS转换与动画轻松的方式。它是受到了无与伦比的ng-animate库启发而创作的。

开始

ReactCSSTransitionGroup是ReactTransitions的接口。用一个简单的元素,将所有的具有动画效果的组件包裹起中。下面是个例子使列表元素淡入淡出。

 1 var ReactCSSTransitionGroup = React.addons.CSSTransitionGroup;
 2 var MyComponent = React.createClass({
 3     getInitialState: function() {
 4         return {items: ["hello", "world", "click", "me"]};
 5     },
 6 
 7     handleAdd: function() {
 8         var newItems = this.state.items.concat([prompt("Enter some text")]);
 9         this.setState({items: newItems});
10     },
11 
12     handleRemove: function(i) {
13         var newItems = this.state.items;
14         newItems.splice(i, 1);
15         this.setState({items: newItems});
16     },
17 
18     render: function() {
19         var items = this.state.items.map(function(item, i) {
20             return (
21                 <div key={item} onClick={this.handleRemove.bind(this, i)}>
22                     {item}
23                 </div>
24             );
25         }.bind(this));
26 
27         return (
28             <div>
29                 <button onClick={this.handleAdd}>Add Item</button>
30                 <ReactCSSTransitionGroup transitionName="example">
31                     {items}
32                 </ReactCSSTransitionGroup>
33             </div>
34         );
35     }
36 });

 

注意:你必须为ReactCSSTransitionGropu的子元素提供key属性,哪怕是只有一个元素。React依据它来决定哪个子元素进入,离开或停留。

在这个组件中,当一个新的元素添加到ReactCSSTransitionGroup后,它将会得到一个example-enter的CSS类,并在下一个时钟添加类名example-enter-active。这是一个基于transitionName属性的约定。

你可以使用这些类来触发CSS动作和转换。例如,试着添加下面的CSS并添加一个元素看看效果:

1 .example-enter {
2     opacity: .01;
3     transition: opacity .5s ease-in;
4 }
5 
6 .example-enter.example-enter-active {
7     opacity: 1;
8 }

 

你会注意到等你删除一个ReactCSSTransitionGroup的子元素的时候,它依然还在。如果你使用的是未压缩的带有扩展的React版本,你会看到一条警告,React期待一个动画或转换发生。因为ReactCSSTransitionGroup会保持DOM元素存在于页面上直到动作完成。试着添加下面的CSS代码:

1 .example-leave {
2     opacity: 1;
3     transition: opacity .5s ease-in;
4 }
5 
6 .example-leave.example-leave-active {
7     opacity: .01;
8 }

 

动画组必须是已经挂载的才能正常工作

为了给它的子元素应用转换,ReactCSSTransitionGroup必须已经存在于DOM中。下面的例子不会正常工作,因为ReactCSSTransitionGroup是随着新的元素添加而添加的,而不是新元素添加在其之内。对比一下上面的开始章节看看它们的不同之处。

 1 render: function() {
 2     var items = this.state.items.map(function(item, i) {
 3         return (
 4             <div key={item} onClick={this.handleRemove.bind(this, i)}>
 5                 <ReactCSSTransitionGroup transitionName="example">
 6                     {item}
 7                 </ReactCSSTransitionGroup>
 8             </div>
 9         );
10     }.bind(this));
11 
12     return (
13         <div>
14             <button onClick={this.handleAdd}>Add Item</button>
15             {items}
16         </div>
17     );
18 }

 

为一个或另个元素添加动画效果

虽然在上面的实例中,我们渲染了一个列表到ReactCSSTransitionGroup中,ReactCSSTransitionGroup的子元素可以是一个或零个。这就有可能为一个单独的元素添加入出的动画。同样的,你可以通过替换当前的元素来为一个新元素添加动画,当前的动画结束后新元素的动画开始。例如,我们来实现一个简单的图片轮播效果:

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

 

禁用动画

如果你需要可以禁用enter或leave动画。例如,有时你只需要enter的动画效果不需要leave的,但是ReactCSSTransitionGroup会在移除DOM节点之前等待动画完成。你可以添加transitionEenter={false}或transitionLeave={false}属性来禁用ReactCSSTransitionGroup的动画效果。

注意:当使用ReactCSSTransitionGroup的时候,你的组件没有办法在转换结束的时候收到通知或提示,或者无法执行复杂的动画逻辑。如果你需要更精细的动画控制,可以使用低级接口ReactTransitionGropu,它提供了自定义转换的钩子。

低级接口:ReactTransitionGropu

ReactTranstionGroup是动画的基础。可以通过React.addons.TransitionGroup访问。当子元素从其中声明添加或移除的时候(就像上面例子中的那样),指定的生命周期钩子会被调用。

componentWillEnter(callback)

在组件添加到一个已经存在的TransitonGroup时,它会和componentDidMount()一起被调用。他会阻塞其他动画的发生知道callback被调用。在初始化渲染一个TransitionGroup的时候,它不会被调用。

componentDidEnter()

它会在callback传递到被调用的componentWillEnter之后被调用。

componentWillLeave(callback)

它会在子元素从ReactTransitionGroup中移除时被调用。虽然子元素被移除了,ReactTransitionGroup会保留它在DOM中,直到callback被执行。

componentDidLeave()

当willLeave callback被调用是执行它(与componentWillUnmount同时执行)。

渲染不同的组件

默认的TractTransitionGroup渲染为一个span。你可以通过提供一个component属性类改变这种行为。例如,这里是如何渲染一个<ul>:

1 <ReactTransitionGroup component="url">
2 ...
3 </ReactTransitionGroup>

 

任一DOM元素都可以被React有效的渲染使用。然而,component属性不是必须为DOM元素。它可以是任何React元素,甚至是你自己的实现的元素。

注意:在版本0.12之前,当使用DOM元素时,component属性必须要为React.DOM.*的引用。因为组件是被React.createElement来解析,它必须是一个字符串。复合组件必须为工厂方法解析。

其他的用户定义的属性将会变成渲染后的组件的属性呈现。例如,这里是如何为渲染的<ul>添加css类名:

1 <ReactTransitionGroup component="url" className="animated-list">
2 ...
3 </ReactTransitionGroup>

 

posted on 2015-04-28 14:49  古道倦马  阅读(1329)  评论(0编辑  收藏  举报

导航