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队列,可以用于构建锁或者其他相关同步装置的基础框架.该同 ...
最新文章
- React +antd +wangEditor 富文本编辑器
- 智源人工智能算法大赛开锣,百万奖金激励 AI 算法创新
- Oracle创建数据库(手动)
- Ocelot(二)- 请求聚合与负载均衡
- 磁盘镜像工具Guymager
- 知识体系地图模型:你是如何有效地学习?
- [HOW TO]-下载android官方源码
- promise间隔时间添加dom
- Java面向对象(二、继承)
- django-oscar-paypal出现UnicodeEncodeError: 'latin-1' codec can't encode characters in position XXXX
- easymock 图片_数据模拟神器 easy-mock 正式开源
- 合唱团算法(DP问题)
- java传输对象_如何传输Java对象
- 新拟物素材|UI设计领域必掌握的要领!
- Python3之logging模块
- ASP.NET没有魔法——ASP.NET Identity的加密与解密
- July面试题整理系列(1)
- 计算机系统是无形资产吗,计算机操作系统做为无形资产核算吗
- 商城订单实时语音提醒功能JavaScript部分 附提醒语音音频文件
- 解决WinHTTP Web Proxy Auto-Discovery Service无法启动问题
热门文章
- 亿牛云API优质代理使用中出现的问题
- python人工智能图像识别视频下载链接_2019-07-11 人工智能-图像识别项目分析-基于tensorflow的视频物品检测...
- MySQL小练习(仅适合初学者,非初学者勿进)
- 【java初学】过滤器,ServletContext和JSP
- 数据库-----catalog与schema简介
- 华为机考108题(c++)(81-90)
- php页面锚点,html 锚点三种实现方法
- java后台图片跨域上传
- 全世界最伤心的人 - 歌词
- 前端开发中关于网络的那些事儿--基础篇