setState原理
setSate接受两个参数,一个是state,另一个是回调函数
注意点:
- 主要是通过队列机制实现state更新,当执行setState的时候,会将需要更新的state合并后放入状态队列中,而不会立即更新this.state。队列机制主要实现了批量更新state。
- 如果我们不使用setState更新,而是直接采用this.state来修改,state不会被放入状态队列中,下次调用setState时对状态队列进行合并时,会忽略之前修改的state,就不会达到预期效果。
- setState不保证是同步的,也可以认为是异步的,在setState之后,会对state进行diff,判断是否有改变,然后去diff是否要更新UI
内部实现:
判断isBatchingUpdates是否为true,为true,则会把当前组件放入dirtyComponents 数组中,否则batchUpdate 所有队列中的更新
var batchingStrategy = {isBatchingUpdates: false,batchedUpdates: function(callback, a, b, c, d, e) {// ...batchingStrategy.isBatchingUpdates = truetransaction.perform(callback, null, a, b, c, d, e); //事务}
};
事务流
transaction实际上做的事情就是将要执行的method使用wrapper封装起来,用提供的perform方法来调用method。在调用的过程中,会先顺序调用wrapper中注册的initialize方法,然后执行method方法,最后顺序调用wrapper中注册的close方法。initialize和close可以是调用transaction的模块自定义的。
例题
componentDidMount() {this.setState({val: this.state.val + 1});console.log(this.state.val); // 第 1 次 logthis.setState({val: this.state.val + 1});console.log(this.state.val); // 第 2 次 logsetTimeout(() => {this.setState({val: this.state.val + 1});console.log(this.state.val); // 第 3 次 logthis.setState({val: this.state.val + 1});console.log(this.state.val); // 第 4 次 log}, 0);}
输出 0 0 2 3
两个调用栈
- 两类调用栈相比,显然第1个调用栈更加复杂。在第1个调用栈中,发现调用setState前出现了close,perform,batchedUpdates等调用。原来在调用setState,执行流已经处于一个transaction中了。
- 在往前分析,可以发现是_renderNewRootComponent方法调用了batchedUpdates,原来整个React Component的渲染过程就处在一个transaction中。
- 这样就可以理解为什么第1次和第2次的setState执行后值没变了。因为在ComponentDidMount中调用setState时,渲染周期还没有结束,batchingStrategy中的isBatchingUpdates还是true,setState对应的components被存入dirtyComponents暂存起来,所以前2次setState之后的this.state.val的结果都是 0。
- 再观察第2类调用栈,使用了setTimeout,会在结束当前调用栈之后执行,这时渲染周期已经结束,batchingStrategy中的isBatchingUpdates为false。setState会在执行流中调用,不会进入dirtyComponents存储,所以新的state会立马生效,打印第3次和第4次的this.state.val,就会出现生效后的值了。
借鉴文章1 | 文章2
setState原理相关推荐
- 这一把子彻底搞懂 setState 原理
这上一篇中,我们基本搞清楚了原理流程,那具体的代码是如何实现的呢? 在 setState 的调用中,有一个合成事件起到了关键性的作用.接下来,我们先去搞清楚这个小可爱,再来看具体的 setState ...
- react16常见api以及原理剖析
Vue 与 React 两个框架的粗略区别对比 Vue 的优势包括: 模板和渲染函数的弹性选择 简单的语法及项目创建 更快的渲染速度和更小的体积 React 的优势包括: 更适用于大型应用和更好的可测 ...
- React16常用api解析以及原理剖析
React16常用api解析以及原理剖析 目录 Vue 与 React 两个框架的粗略区别对比 react 16 版本常见 api react 生命周期 react 事件机制 react.Compon ...
- 前22年的Loser,后4年和自己赛跑的人 | 最惨前端面经
跳槽原因 前东家部门是做旅游的,在这次疫情打击下,基本玩完. 于是我半休半远程三个月后,在4月底领了裁员便当.至今,差不多找了两个月的工作. 本篇不是标准的面经,想从中获取大厂跳槽经验的可以歇一歇. ...
- 学习掘金React进阶实践指南笔记(三)玄学state
1.初步了解state和setState 需要知道类的state,以及this.setState的参数是一个对象与一个回调函数的区别(如果是对象多次调用会合并,如果是函数下一个setState可以依赖 ...
- 前端面试中小型公司都考些什么
两栏布局的实现 一般两栏布局指的是左边一栏宽度固定,右边一栏宽度自适应,两栏布局的具体实现: 利用浮动,将左边元素宽度设置为200px,并且设置向左浮动.将右边元素的margin-left设置为200 ...
- _improve-3
createElement过程 React.createElement(): 根据指定的第一个参数创建一个React元素 React.createElement(type,[props],[...ch ...
- [react] react多个setState调用的原理是什么?
[react] react多个setState调用的原理是什么? 同步调用多个setState,React并不会连续多次的进行更新操作,而是会将同步中的多个setState操作合成一个,只执行一次re ...
- 转:AbstractQueuedSynchronizer的介绍和原理分析
引自:http://ifeve.com/introduce-abstractqueuedsynchronizer/ 简介 提供了一个基于FIFO队列,可以用于构建锁或者其他相关同步装置的基础框架.该同 ...
最新文章
- 想从事分布式系统,计算,hadoop等方面,需要哪些基础,推荐哪些书籍?--转自知乎...
- 使用 Dockerfile 定制镜像
- UDP和TCP协议包大小的计算
- 直观判断图像是否可以被实时处理
- vsftp虚拟用户无法上传文件,解决办法
- NetBeans可用性提示
- WINCE6补丁安装
- 增加RIL组件时编辑出现的问题
- 如何把握网络工程师的“钱”途,专访文字。
- 使用HttpURLConnection+AsyncTask访问webservice接口(返回json字符串)
- Cortex - M3 一些基础知识
- C++指针、空指针、野指针使用的一些总结
- 联想System x服务器主要硬件Windows Server驱动下载
- 汽车仪表指示灯详细介绍
- 用idea对git的merge进行撤销
- contos7 配置 python3环境 支持微信公众号开发
- office2016 无法启动服务,原因可能是已被禁用或与其相关联的设备没有启动
- 论语读后感--论语与管理
- 怎样打印微信文档文件?
- 机器学习之线性回归:OLS 无偏估计及相关性python分析