React的Transaction浅析
1.两个示例
- 示例1
let SonClass = React.createClass({
render: function(){
console.log("render", this.props.num);
return null;
},
componentDidMount: function(){
console.log('componentDidMount', this.props.num);
}
});
let FatherClass = React.createClass({
render:function(){
return (
<div>
<SonClass num="one" />
<SonClass num="two" />
</div>
)
}
});
ReactDOM.render( <FatherClass /> ,
document.getElementById("test")
);
输出为
render *2
componentDidMount *2
- 示例2
let React = require('react');
let ReactDOM = require('react-dom');
let Hello = React.createClass({
getInitialState: function() {
return {
clicked: 0
};
},
handleClick: function() {
this.setState({
clicked:this.state.clicked + 1
});
this.setState({
clicked: this.state.clicked + 1
});
},
render: function() {
return <button onClick = {
this.handleClick
} > {
this.state.clicked
} </button>;
}
});
ReactDOM.render( <Hello /> ,
document.getElementById("test")
);
点击后this.state.clicked递增1,而不是递增2。
2.解释
首先介绍React的Transaction。
其源码在React/lib/Transaction.js。
Transaction就是给需要执行的方法fn用wrapper封装了 initialize 和 close 方法。且支持多次封装。再通过 Transaction 提供的 perform 方法执行。 perform执行前,调用所有initialize 方法。perform 方法执行后,调用所有close方法。
Transaction的use case是
- Preserving the input selection ranges before/after reconciliation.
Restoring selection even in the event of an unexpected error. - Deactivating events while rearranging the DOM, preventing blurs/focuses,
while guaranteeing that afterwards, the event system is reactivated. - Flushing a queue of collected DOM mutations to the main UI thread after a
reconciliation takes place in a worker thread. - Invoking any collected
componentDidUpdatecallbacks after rendering new
content. - (Future use case): Wrapping particular flushes of the
ReactWorkerqueue
to preserve thescrollTop(an automatic scroll aware DOM). - (Future use case): Layout calculations before and after DOM updates.
示例一,对应的是第4点use case。整个生命周期就是一个Transaction,在Transaction执行期间,componentDidUpdate方法被推入一个队列中。DOM reconciliation后,再调用队列中的所有componentDidUpdate。
示例二,对应的是第3点use case。react的事件回调也是一个Transaction。handleClick里面的this.setState不会马上生效,而是先通过 ReactUpdates.batchedUpdate 方法存入临时队列。所以每次setState时,拿到的this.state.clicked都是初始值。直到transaction 完成,通过ReactUpdates.flushBatchedUpdates方法进行UI更新。
更详细的流程参考此图

3.参考文章(强烈推荐去看)
http://undefinedblog.com/what-happened-after-set-state/
http://zhuanlan.zhihu.com/purerender/20328570
React的Transaction浅析的更多相关文章
- React虚拟DOM浅析
在Web开发中,需要将数据的变化实时反映到UI上,这时就需要对DOM进行操作,但是复杂或频繁的DOM操作通常是性能瓶颈产生的原因,为此,React引入了虚拟DOM(Virtual DOM)的机制. 什 ...
- React生命周期浅析
引言 关于React的生命周期API,官网,有着详细说明.但在实际写代码的过程中,这些说明不能解决所有的疑惑. 所以我列举了一些编码中常见用例,供大家参考. 示例代码如下 /* use case 1. ...
- 使用Redux管理React数据流要点浅析
在图中,使用Redux管理React数据流的过程如图所示,Store作为唯一的state树,管理所有组件的state.组件所有的行为通过Actions来触发,然后Action更新Store中的stat ...
- react diff算法浅析
diff算法作为Virtual DOM的加速器,其算法的改进优化是React整个界面渲染的基础和性能的保障,同时也是React源码中最神秘的,最不可思议的部分 1.传统diff算法计算一棵树形结构转换 ...
- React Native初探
前言 很久之前就想研究React Native了,但是一直没有落地的机会,我一直认为一个技术要有落地的场景才有研究的意义,刚好最近迎来了新的APP,在可控的范围内,我们可以在上面做任何想做的事情. P ...
- React 组件性能优化
React组件性能优化 前言 众所周知,浏览器的重绘和重排版(reflows & repaints)(DOM操作都会引起)才是导致网页性能问题的关键.而React虚拟DOM的目的就是为了减少浏 ...
- [React] 10 - Tutorial: router
Ref: REACT JS TUTORIAL #6 - React Router & Intro to Single Page Apps with React JS Ref: REACT JS ...
- 【优质】React的学习资源
React的学习资源 github 地址: https://github.com/LeuisKen/react-collection https://github.com/reactnativecn/ ...
- React Native指南汇集了各类react-native学习资源、开源App和组件
来自:https://github.com/ele828/react-native-guide React Native指南汇集了各类react-native学习资源.开源App和组件 React-N ...
随机推荐
- Python脚本模拟登录网页之CSDN篇
1. 通过Firefox配合插件Tamper Date获取登录时客户端向服务器端提交的数据, 并且发现lt和execution这两个字段每次登录时都不一样. POSTDATA=username=you ...
- CSS权威指南 - 基本视觉格式化 4
改变元素显示 没有讨论与表格相关的.列表list-item的值.之后讨论. 改变显示角色 显示为块级元素 将一串链接(行内元素)改变垂直放置,若有如下一连串的链接: <div id=" ...
- linux下开启防火墙,打开端口
service iptables start时提示:“iptables: No config file. [WARNING]” 此时打 ...
- 【Android测试】【第十六节】Instrumentation——初识+实战
◆版权声明:本文出自胖喵~的博客,转载必须注明出处. 转载请注明出处:http://www.cnblogs.com/by-dream/p/5503645.html 前言 有朋友给我留言说,能否介绍一下 ...
- C#编程之委托与事件四(一)【转】
C#编程之委托与事件(一) 本文试图在.net Framework环境下,使用C#语言来描述委托.事件的概貌.希望本文能有助于大家理解委托.事件的概念,理解委托.事件的用途,理解它的C#实现方 ...
- C#的默认可访问性级别
1.在namespace中的类.接口默认是internal类型的,也可以显示的定义为public类型,不允许是其他访问类型.2.在一个类里面,属性和方法默认是private的,可以显示的定义为publ ...
- Android应用程序窗口(Activity)的视图对象(View)的创建过程分析
从前文可知道,每一个Activity组件都有一个关联的Window对象,用来描述一个应用程序窗口.每一个应用程序窗口内部又包含有一个View对象,用来描述应用程序窗口的视图.应用程序窗口视图是真正用来 ...
- 12个css高级技巧.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- Android -- 使用ViewPager实现画廊效果
1,今天在微信推送文章看到实现画廊效果,感觉挺不错的,就来写写试试,先来看一下效果图: 上面的效果基本上可以用两个功能点来包含:ViewPager的切换动画.ImageView的倒影的实现 嗯,先来将 ...
- ajax+jquery+ashx如何实现上传文件
第一:建立Default.aspx页面 <html> <head runat="server"> <title>ajax图片上传</tit ...