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. React +antd +wangEditor 富文本编辑器
  2. 智源人工智能算法大赛开锣,百万奖金激励 AI 算法创新
  3. Oracle创建数据库(手动)
  4. Ocelot(二)- 请求聚合与负载均衡
  5. 磁盘镜像工具Guymager
  6. 知识体系地图模型:你是如何有效地学习?
  7. [HOW TO]-下载android官方源码
  8. promise间隔时间添加dom
  9. Java面向对象(二、继承)
  10. django-oscar-paypal出现UnicodeEncodeError: 'latin-1' codec can't encode characters in position XXXX
  11. easymock 图片_数据模拟神器 easy-mock 正式开源
  12. 合唱团算法(DP问题)
  13. java传输对象_如何传输Java对象
  14. 新拟物素材|UI设计领域必掌握的要领!
  15. Python3之logging模块
  16. ASP.NET没有魔法——ASP.NET Identity的加密与解密
  17. July面试题整理系列(1)
  18. 计算机系统是无形资产吗,计算机操作系统做为无形资产核算吗
  19. 商城订单实时语音提醒功能JavaScript部分 附提醒语音音频文件
  20. 解决WinHTTP Web Proxy Auto-Discovery Service无法启动问题

热门文章

  1. 亿牛云API优质代理使用中出现的问题
  2. python人工智能图像识别视频下载链接_2019-07-11 人工智能-图像识别项目分析-基于tensorflow的视频物品检测...
  3. MySQL小练习(仅适合初学者,非初学者勿进)
  4. 【java初学】过滤器,ServletContext和JSP
  5. 数据库-----catalog与schema简介
  6. 华为机考108题(c++)(81-90)
  7. php页面锚点,html 锚点三种实现方法
  8. java后台图片跨域上传
  9. 全世界最伤心的人 - 歌词
  10. 前端开发中关于网络的那些事儿--基础篇