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原理相关推荐

  1. 这一把子彻底搞懂 setState 原理

    这上一篇中,我们基本搞清楚了原理流程,那具体的代码是如何实现的呢? 在 setState 的调用中,有一个合成事件起到了关键性的作用.接下来,我们先去搞清楚这个小可爱,再来看具体的 setState ...

  2. react16常见api以及原理剖析

    Vue 与 React 两个框架的粗略区别对比 Vue 的优势包括: 模板和渲染函数的弹性选择 简单的语法及项目创建 更快的渲染速度和更小的体积 React 的优势包括: 更适用于大型应用和更好的可测 ...

  3. React16常用api解析以及原理剖析

    React16常用api解析以及原理剖析 目录 Vue 与 React 两个框架的粗略区别对比 react 16 版本常见 api react 生命周期 react 事件机制 react.Compon ...

  4. 前22年的Loser,后4年和自己赛跑的人 | 最惨前端面经

    跳槽原因 前东家部门是做旅游的,在这次疫情打击下,基本玩完. 于是我半休半远程三个月后,在4月底领了裁员便当.至今,差不多找了两个月的工作. 本篇不是标准的面经,想从中获取大厂跳槽经验的可以歇一歇. ...

  5. 学习掘金React进阶实践指南笔记(三)玄学state

    1.初步了解state和setState 需要知道类的state,以及this.setState的参数是一个对象与一个回调函数的区别(如果是对象多次调用会合并,如果是函数下一个setState可以依赖 ...

  6. 前端面试中小型公司都考些什么

    两栏布局的实现 一般两栏布局指的是左边一栏宽度固定,右边一栏宽度自适应,两栏布局的具体实现: 利用浮动,将左边元素宽度设置为200px,并且设置向左浮动.将右边元素的margin-left设置为200 ...

  7. _improve-3

    createElement过程 React.createElement(): 根据指定的第一个参数创建一个React元素 React.createElement(type,[props],[...ch ...

  8. [react] react多个setState调用的原理是什么?

    [react] react多个setState调用的原理是什么? 同步调用多个setState,React并不会连续多次的进行更新操作,而是会将同步中的多个setState操作合成一个,只执行一次re ...

  9. 转:AbstractQueuedSynchronizer的介绍和原理分析

    引自:http://ifeve.com/introduce-abstractqueuedsynchronizer/ 简介 提供了一个基于FIFO队列,可以用于构建锁或者其他相关同步装置的基础框架.该同 ...

最新文章

  1. 想从事分布式系统,计算,hadoop等方面,需要哪些基础,推荐哪些书籍?--转自知乎...
  2. 使用 Dockerfile 定制镜像
  3. UDP和TCP协议包大小的计算
  4. 直观判断图像是否可以被实时处理
  5. vsftp虚拟用户无法上传文件,解决办法
  6. NetBeans可用性提示
  7. WINCE6补丁安装
  8. 增加RIL组件时编辑出现的问题
  9. 如何把握网络工程师的“钱”途,专访文字。
  10. 使用HttpURLConnection+AsyncTask访问webservice接口(返回json字符串)
  11. Cortex - M3 一些基础知识
  12. C++指针、空指针、野指针使用的一些总结
  13. 联想System x服务器主要硬件Windows Server驱动下载
  14. 汽车仪表指示灯详细介绍
  15. 用idea对git的merge进行撤销
  16. contos7 配置 python3环境 支持微信公众号开发
  17. office2016 无法启动服务,原因可能是已被禁用或与其相关联的设备没有启动
  18. 论语读后感--论语与管理
  19. 怎样打印微信文档文件?
  20. 机器学习之线性回归:OLS 无偏估计及相关性python分析

热门文章

  1. 零基础CSS入门教程(18)–颜色值
  2. 分析:谁能抗衡巨人和阿里巴巴(转)
  3. 谷歌留痕,批量关键词组合+URL编码工具极速版
  4. 四针脚0.96寸OLED屏幕标准库代码转Cube Max创建的HAL库工程代码
  5. php里drear_根基_吴明科_大路画展 - 出山网
  6. 概念辨析|电子文件单轨制与电子档案单套制
  7. 设备监理师证书含金量怎样?值得考吗?
  8. 水晶头镀金30U和50区别
  9. Flink Checkpoint源码浅析
  10. HDU 悼念512汶川大地震遇难同胞——老人是真饿了