state 用于控制元素是否显示,另一个 state 用于控制元素在动画中的变化属性。在这种情况下,开发者需要花费大量精力来维护组件的动画逻辑,十分复杂繁琐。
三、React 动画插件 CssTransitionGroup
React 曾为开发者提供过动画插件 react-addons-css-transition-group ,后交由社区维护,形成现在的 react-transition-group ,该插件可以方便地实现组件的入场和离场动画,使用时需要开发者额外安装。 react-transition-group 包含 CSSTransitionGroup 和 TransitionGroup 两个动画插件,其中,后者是底层 api,前者是后者的进一步封装,可以较为便捷地实现 css 动画。
示例
以一个动态增加tab的为例,代码如下:
import React, { Component } from 'react';
import { CSSTransitionGroup } from 'react-transition-group';
let uid = 2;
export default class Tabs extends Component {
constructor(props) {
super(props);
this.state = {
activeId: 1,
tabData: [{
id: 1,
panel: '选项1'
}, {
id: 2,
panel: '选项2'
}]
};
}
addTab = () => {
// 添加tab代码
...
}
deleteTab = (id) => {
// 删除tab代码
...
}
render() {
const { tabData, activeId } = this.state;
const renderTabs = () => {
return tabData.map((item, index) => {
return (
<div
className={`tab-item${item.id === activeId ? ' tab-item-active' : ''}`}
key={`tab${item.id}`}
>
{item.panel}
<span className="btns btn-delete" onClick={() => this.deleteTab(item.id)}>✕</span>
</div>
);
})
}
return (
<div>
<div className="tabs" >
<CSSTransitionGroup
transitionName="tabs-wrap"
transitionEnterTimeout={500}
transitionLeaveTimeout={500}
>
{renderTabs()}
</CSSTransitionGroup>
<span className="btns btn-add" onClick={this.addTab}>+</span>
</div>
<div className="tab-cont">
cont
</div>
</div>
);
}
}
/* tab动态增加动画 */
.tabs-wrap-enter {
opacity: 0.01;
}
.tabs-wrap-enter.tabs-wrap-enter-active {
opacity: 1;
transition: all 500ms ease-in;
}
.tabs-wrap-leave {
opacity: 1;
}
.tabs-wrap-leave.tabs-wrap-leave-active {
opacity: 0.01;
transition: all 500ms ease-in;
}
CSSTransitionGroup 可以为其子节点添加额外的 css 类,然后通过 css 动画达到入场和离场动画效果。为了给每个 tab 节点添加动画效果,需要先将它们包裹在 CSSTransitionGroup 组件中。 当设定
