Animation in React
liyang24 @meituan
传统方式
// JQuery
$('selector').animate({params},speed,callback);
// Velocity.js
Velocity(document.getElementById('dummy'),
{ opacity: 0.5 }, { duration: 1000 }
);
- 先获取具体的DOM结点
- 然后通过操作DOM的方式附加动画特效
- 你操作的是虚拟DOM,而真正的DOM由React统一来处理
- 等React组件每次渲染好了,再操作具体的DOM结点
第一种:操作真实DOM
React组件切入动画的两种途径
第二种:操作虚拟DOM
- 通过props,state等数据驱动动画
- 操作DOM的具体时机
- 如何避免与React 组件DOM操作间的冲突
React组件生命周期
Model Data
- props
- state
Lifecycle Methods
-
getInitialState(constructor)
-
componentWillMount
-
componentDidMount
-
componentWillReceiveProps
-
shouldComponentUpdate
-
componentWillUpdate
-
componentDidUpdate
-
componentWillUnmount
-
render
First Render
Props Change
State Change
Unmount
-
React + CSS Transition => real DOM
-
React + Data Driven (props, state) => virtual DOM
React + CSS Transition
如何使用?
<ReactCSSTransitionGroup
transitionName="toggle"
component="div"
transitionEnter={true}
transitionEnterTimeout={800}
transitionLeave={true}
transitionLeaveTimeout={800}
transitionAppear={true}
transitionAppearTimeout={800}>
<img key={key}
src="http://mc.meituan.net/touch/css/download/i/ph1.png"/>
</ReactCSSTransitionGroup>
.toggle-appear {...}
.toggle-appear.toggle-appear-active {...}
.toggle-enter {...}
.toggle-enter.toggle-enter-active {...}
.toggle-leave {...}
.toggle-leave.toggle-leave-active {...}
Demo
实现逻辑 & 缺陷
ReactCSSTransitionGroup容器中,如果有设置了props key值React组件,当key值发生变动时(可以理解成React组件加入容器或从容器中移除),会经历如下六个生命周期:
- componentWillAppear(callback)
- componentDidAppear()
- componentWillEnter(callback)
- componentDidEnter()
- componentWillLeave(callback)
- componentDidLeave()
- 添加class
- 删除class
在一定时间间隔内,进行如下两个操作:
- 动画组件的生命周期定义由更加底层的TransitionGroup实现
- http://facebook.github.io/react/blog/2015/10/07/react-v0.14.html
- 官方源码
ReactCSSTransitionGroup容器的细节实现举例
componentWillEnter (callback) {
const nd = React.findDOMNode(this);
nd.classList.add(styles.enter);
setTimeout(() => {
nd.classList.add(styles.active)
}, timeout);
/*nd.addEventListener('transitionend', () => {
if (callback) {
callback();
}
nd.classList.remove(styles.enter);
nd.classList.remove(styles.active);
});*/
setTimeout(() => {
nd.classList.remove(styles.enter);
nd.classList.add(styles.active);
}, this.props.transitionEnterTimeout);
}
拿到真实的DOM
加class
删class
-
ReactCSSTransitionGroup Issues
-
某种程度上破坏掉了React 组件固有的生命周期
- react.css.transition (冗余DOM)
- @mtfe/md.calendar (卡顿)
缺陷
React + Data Driven (props, state)
setInterval(() => {
this.setState({x: this.state.x + 1})
}, 500);
最暴力的一个实例:
一个SVG 动画Demo:react.css.transition
- velocity-react: Velocity.js + React
- React-Motion
React动画相关的开源工具
相关资源
谢谢!
Animation in React
By Ivan Lyons
Animation in React
探索一下下寫React組件時添加動畫特效時的細枝末節。
- 4,198