CSSTransitionGroup 实现动画的优点是:
- 简单易用,可以方便快捷地实现元素的入场和离场动画;
- 与 React 结合,性能比较好。
CSSTransitionGroup 缺点也十分明显:
- 局限于出现动画,入场动画和离场动画;
- 由于需要制定
transitionName,灵活性不够; - 只能依靠 css 实现简单的动画。
四、结合 hook 实现复杂动画
在实际项目中,可能需要一些更炫酷的动画效果,这些效果仅依赖于 css3 往往较难实现。此时,我们不妨借助一些成熟的第三方库,如 jQuery 或 GASP,结合 React 组件中的生命周期钩子方法 hook 函数,实现复杂动画效果。除了 React 组件正常的生命周期外, CSSTransitionGroup 的底层 api TransitonGroup 还为其子元素额外提供了一系列特殊的生命周期 hook 函数,在这些 hook 函数中结合第三方动画库可以实现丰富的入场、离场动画效果。
TransisitonGroup 分别提供一下六个生命周期 hook 函数:
- componentWillAppear(callback)
- componentDidAppear()
- componentWillEnter(callback)
- componentDidEnter()
- componentWillLeave(callback)
- componentDidLeave()
它们的触发时机如图所示:

示例
GASP 是一个 flash 时代发展至今的动画库,借鉴视频帧的概念,特别适合做长时间的序列动画效果。本文中,我们用 TransitonGroup 和 react-gsap-enhancer (一个可以将 GSAP 应用于 React 的增强库)完成一个图片画廊,代码如下:
import React, { Component } from 'react';
import { TransitionGroup } from 'react-transition-group';
import GSAP from 'react-gsap-enhancer'
import { TimelineMax, Back, Sine } from 'gsap';
class Photo extends Component {
constructor(props) {
super(props);
}
componentWillEnter(callback) {
this.addAnimation(this.enterAnim, {callback: callback})
}
componentWillLeave(callback) {
this.addAnimation(this.leaveAnim, {callback: callback})
}
enterAnim = (utils) => {
const { id } = this.props;
return new TimelineMax()
.from(utils.target, 1, {
x: `+=${( 4 - id ) * 60}px`,
autoAlpha: 0,
onComplete: utils.options.callback,
}, id * 0.7);
}
leaveAnim = (utils) => {
const { id } = this.props;
return new TimelineMax()
.to(utils.target, 0.5, {
scale: 0,
ease: Sine.easeOut,
onComplete: utils.options.callback,
}, (4 - id) * 0.7);
}
render() {
const { url } = this.props;
return (
<div className="photo">
<img src={url} />
</div>
)
}
}
const WrappedPhoto = GSAP()(Photo);
export default class Gallery extends Component {
constructor(props) {
super(props);
this.state = {
show: false,
photos: [{
id: 1,
url: 'http://img4.imgtn.bdimg.com/it/u=1032683424,3204785822&fm=214&gp=0.jpg'
}, {
id: 2,
url: 'http://imgtu.5011.net/uploads/content/20170323/7488001490262119.jpg'
}, {
id: 3,
url: 'http://tupian.enterdesk.com/2014/lxy/2014/12/03/18/10.jpg'
}, {
id: 4,
url: 'http://img4.imgtn.bdimg.com/it/u=360498760,1598118672&fm=27&gp=0.jpg'
}]
};
}
toggle = () => {
this.setState({
show: !this.state.show
})
}
render() {
const { show, photos } = this.state;
const renderPhotos = () => {
return photos.map((item, index) => {
return <WrappedPhoto id={item.id} url={item.url} key={`photo${item.id}`} />;
})
}
return (
<div>
<button onClick={this.toggle}>toggle</button>
<TransitionGroup component="div">
{show && renderPhotos()}
</TransitionGroup>
</div>
);
}
}
内容版权声明:除非注明,否则皆为本站原创文章。
