官方文档 参考文档 参考文档
React 提供了一个 ReactTransitionGroup
插件作为动画的底层API,和一个 ReactCSSTransitionGroup
用于轻松实现基础的CSS动画和过渡。
一、ReactCSSTransitionGroup基本使用
ReactCSSTransitionGroup
基于 ReactTransitionGroup
是一个当React组件进入或离开DOM时,执行CSS动画和过渡的简单方法。它的灵感来自于杰出的 ng-animate 库。ReactCSSTransitionGroup
是 ReactTransitions
的接口实现。这是一个简单的元素,包裹了所有你感兴趣的动画组件。这里是一个淡入和淡出列表项目的例子。
import React from 'react'
import '@/css/demo1.css'
export default class Demo1 extends React.Component{
constructor(props){
super(props);
this.state = {
items: ['hello', 'world', 'click', 'me']
};
}
//渲染页面
render(){
var ReactCSSTransitionGroup = require('react-addons-css-transition-group');
//items 得到 [<div>hello</div>,<div>world</div>,....]
var items = this.state.items.map((item,i)=>{
return (
<div key={item} onClick={()=>{this.handleRemove({i})}}>
{item}
</div>
);
});
return (
<div>
{/*点击按钮执行添加*/}
<button onClick={()=>{this.handleAdd()}}>Add Item</button>
{/*把要动画的元素用ReactCSSTransitionGroup包裹起来*/}
<ReactCSSTransitionGroup component="ul" transitionName="example"
transitionEnterTimeout={500} transitionLeaveTimeout={300}>
{items}
</ReactCSSTransitionGroup>
</div>
);
}
//添加数据的方法
handleAdd = ()=> {
this.setState((state)=>{
return {
items:[prompt('Enter some text'),...state.items]
}
})
}
//移除数据的方法
handleRemove = (i)=> {
var newItems = this.state.items.slice();
newItems.splice(i, 1);
this.setState({items: newItems});
}
}
注意:
你必须为
ReactCSSTransitionGroup
的所有子级提供 key 属性,即使只渲染一个项目。这就是React将决定哪一个子级进入、离开、停留
当一个新的项目被添加到 ReactCSSTransitionGroup
,他将得到 example-enter
CSS类 并且在下一刻example-enter-active
CSS类被添加。这是一个基于transitionName
prop 的约定。
你可以使用这些类来触发CSS动画和过渡。比如,尝试添加这个CSS和添加一个新的列表项:
//demo1.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
类名的对象。
...
<ReactCSSTransitionGroup
transitionName={ {
enter: 'enter',
enterActive: 'enterActive',
leave: 'leave',
leaveActive: 'leaveActive',
appear: 'appear',
appearActive: 'appearActive'
} }>
{item}
</ReactCSSTransitionGroup>
...
四、动画一个或者零个项目
在上面的例子中,我们渲染了一系列的项目到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,它提供了你自定义过渡效果所需要的挂钩。
六、渲染一个不同的组件
默认情况下 ReactTransitionGroup
渲染为一个 span
。你可以通过提供一个 component
prop 来改变这种行为。例如下面是你将如何渲染一个<ul>
:
<ReactTransitionGroup component="ul">
...
</ReactTransitionGroup>
每一个React能渲染的DOM组件都是可用的。然而组件不需要是一个DOM组件。它可以是任何你想要的React组件;甚至是你自己已经写好的!只要写 component={List}
你的组件会收到 this.props.children
(组件的所有子节点)