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 ...
随机推荐
- mysql集群 MySQL Cluster
<?php /* 郑重说明2015年6月11日16:28:14,目前为止MySQL Cluster 社区版不支持INNODB,商业版支持,但是授权价格20W左右,so看此文档之前,考虑下钱 My ...
- J2EE用户CPU占用过大后的分析过程
1.找到最耗CPU的java线程ps命令 命令:ps -mp pid -o THREAD,tid,time 或者 ps -Lfp pid 结果展示: 2.可以获取到 ...
- LightOj 1213 - Fantasy of a Summation(推公式 快速幂)
题目链接:http://lightoj.com/volume_showproblem.php?problem=1213 #include <stdio.h> int cases, case ...
- Maven-010-maven 编译报错:Failure to ... in ... was cached in the local repository, resolution will not be reattempted until the update interval of nexus has elapsed or updates are forced.
今晚在编译 maven 项目的时候,命令行报错,出现 Failure to ... in ... 类似错误,详细的错误信息如下所示: [INFO] -------------------------- ...
- thinkphp多语言设置
thinkphp多语言设置有点'高大上',为什么说它有点'高大上'呢?因为本人设置了好久才弄好,而本人之所以弄了好久的原因,竟然是因为'开启语言设置必须得先开启初始化系统的行为类',所以,在这里,因为 ...
- 【Android测试】【第十二节】Uiautomator——API详解
◆版权声明:本文出自carter_dream的博客,转载必须注明出处. 转载请注明出处:http://www.cnblogs.com/by-dream/p/4921701.html 简单的例子 以一个 ...
- 《奥威Power-BI智能分析报告制作方法 》精彩回顾
上次课我们简单介绍了奥威Power-BI的智能分析报告,并展示了报告与图表相结合的应用场景.图文分析报表的意义不只在于美观,更重要的是固定框架下的灵活性和追根究底的动态分析,有着很强的实用性.上节课 ...
- jquery怎么跳出当前的each循环
有些朋友可能会以为在jquery跳出循环可以直接使用continue和break了,但是使用之后没有效果,因为在jquery中没有这两条命令. 后来上网查了下,得到了结果: return false; ...
- Linux命令之tcpdump
项目中常用到的抓包命令: 1. tcpdump -i eth0:1 udp poort 6015 -Xvv 2. tcpdump host 239.16.101.27 -Xvv 3. tcpdump ...
- Chart 绘制,自带动画效果
package com.example.canvasdemo; import android.annotation.SuppressLint; import android.content.Conte ...