react中的setState的使用和深入理解
前端框架从MVC过渡到MVVM。从DOM操作到数据驱动,一直在不断的进步着,提升着,
angular中用的是watcher对象,vue是观察者模式,react就是state了,他们各有各的特点,没有好坏之分,只有需求不同而选择不同。
今天就着重详细的随手写点我对react中state的理解:
React通过管理状态实现对组件的管理,通过this.state()方法更新state。当this.setState()被调用的时候,React会重新调用render方法来重新渲染UI。
在说setstate这个磨人的小妖精之前,不得不先说一下state这个小可爱了
定义一个合适的State,是正确创建组件的第一步。因为有一些变量不需要响应式的使用,如果使用了state,就会给这个变量增加一些响应式挂载,要时 刻 记得做到完美 ^-^
判断是否可以做为一个state的条件:
1、变量如果是通过props从父组件中获取,就不是一个状态
2、如果这个变量可以通过其他的状态state或者属性props 通过数据处理得到,就不是一个状态
3、如果变量在render中没有使用到,那就不是一个state
4、变量在整个生命周期中都保持不变时,也不是一个状态
其实使用的时候最多的使用到的就是state和props,他们两个是有很大的区别的,最主要的区别就是:
State是可变的,是组件内部维护的一组用于反映组件UI变化的状态集合;
而Props对于使用它的组件来说,是只读的,要想修改Props,只能通过该组件的父组件修改。在组件状态上移的场景中,父组件正是通过子组件的Props, 传递给子组件其所需要的状态。
在使用state的时候, 如果我们企图直接修改state中的某一个值之后直接打印(使用)他,就会发现,他其实并没有改变。
就像下面的例子,企图通过点击事件之后就使用修改之后的state的值,但是会发state中的并没有被立即修改,还是原先的值,我们都知道那是因为 setState就相当于是一个异步操作,不能立即被修改

那么我们也都知道为了解决上面的问题会有很多方法例如:
方法一:

这个回调函数会在修改了state之后才会执行,这就就可以happy的使用修改之后的state的值了
方法二:

操作异步函数,用的最舒服的还是async / await 啦
当然还有很多其他的解决办法啦。。。。。。。。只是我会比较常用这两种方法而已
在使用setState的时候,有两种格式;
第一种setstate()格式 第一个参数是一个对象,第二个参数是一个回调函数,这个回调函数是在setstate执行完并页面渲染了之后再执行

但是这种修改的方式不稳妥,因为是直接修改,我还是比较喜欢使用第二种格式
setstate的第二种格式,接收一个回调函数,而不是一个对象,这个回调函数有两个参数,
一个是接收前一个状态值作为第一个参数,并将更新后的值作为第二个参数

这种写法在这个例子里有点大材小用了,但是在处理复杂数据和逻辑的时候会特别好用 !
总的来说setstate这个磨人的小妖精就和Vue中的数据响应一样,
在Vue中,

Vue官网上偷的图。。。。。。。。。。
组件、函数等渲染---->创建一个虚拟DOM树------->当data、computed、props改变时会引起页面的刷新--------watcher检测变化,当变化以后不会 立 即渲染,会有一个队列,只要观察到数据变化,Vue 将开启一个队列,并缓冲在同一事件循环中发生的所有数据改变。如果同一个 watcher 被多次触 发, 只会被推入到队列中一次。这种在缓冲时去除重复数据对于避免不必要的计算和 DOM 操作上非常重要。然后,在下一个的事件循环“tick”中,Vue 刷 新队列并执行实际 (已去重的) 工作。
在react中

可以看出在react中也是和Vue中的一样,state的值在修改了之后并不会立即被修改,而是也有一个类似的队列,setState通过一个队列机制实现state的更新。当执行setState时,会把需要更新的state合并后放入状态队列,而不会立刻更新this.state,利用这个队列机制可以高效的批量的更新state。
真是一个神奇的方法,很喜欢这个可以高效批量更新state的机制,于是就去瞅了瞅setState的源码,想看一下react是怎么构造出setState这个磨人的小妖精的
这个构造小妖精的过程也是磨人的。。。。。。理了好久才理清。。。。
它的主要流程如下:
1、当调用setState时,实际上会执行enqueueSetState方法,并对partialState以及_pendingStateQueue更新队列进行合并,最终通过enqueueUpdate执行state更新
2、 如果组件当前正处于update事务中,则先将Component存入dirtyComponent中。否则调用batchedUpdates处理。
而performUpdateIfNecessary方法获取_pendingElement、_pendingStateQueue、_pendingForceUpdate,并调用reciveComponent和updateComponent方法进行组件更新。
3、batchedUpdates发起一次transaction.perform()事务
4、开始执行事务初始化,运行,结束三个阶段
初始化:事务初始化阶段没有注册方法,故无方法要执行
运行:执行setSate时传入的callback方法,一般不会传callback参数
结束:更新isBatchingUpdates为false,并执行FLUSH_BATCHED_UPDATES这个wrapper中的close方法
5、FLUSH_BATCHED_UPDATES在close阶段,会循环遍历所有的dirtyComponents,调用updateComponent刷新组件,并执行它的pendingCallbacks, 也就是setState中设置的callback。
源码部分有空补上。。。。。。
react中的setState的使用和深入理解的更多相关文章
- React中的setState到底发生了什么?
https://yq.aliyun.com/ziliao/301671 https://segmentfault.com/a/1190000014498196 https://blog.csdn.ne ...
- 3.React中的setstate的几个现象
转载segfault 上面的一篇文章,https://segmentfault.com/a/1190000014498196 1.在同一个方法中多次setState是会被合并的,并且对相同属性的设置只 ...
- react中this.setState的理解
this.setState作用? 在react中要修改this.state要使用this.setState,因为this.state只是一个对象,单纯的修改state并不会触发ui更新.所以我们需要用 ...
- React中的state与props的再理解
props可以看做是 property 的缩写的复数,可以翻译为属性,类似于HTML 标签的自定义属性.在大多数React教程里讲 state 和 props 主要的区别在于 props 是不可变的, ...
- React中this.setState是同步还是异步?为什么要设计成异步?
在使用react的时候,this.setState为什么是异步呢? 一直以来没有深思这个问题.昨天就此问题搜索了一下. react创始人之一 Dan Abramovgaearon在GitHub上回答了 ...
- react 中的 setState
语法:setState(newState [,callback]) 1.只要有入门基础的同学都知道 setState({...}) 是更新组件中的 state 内容 2.但是,setState 是异步 ...
- React中的setState(obj)
1.setState(obj) 只能浅merge obj,对于复杂对象结构的不行 比如: this.state = { data:{ idx:1 } } this.setState( ...
- 从源码的角度再看 React JS 中的 setState
在这一篇文章中,我们从源码的角度再次理解下 setState 的更新机制,供深入研究学习之用. 在上一篇手记「深入理解 React JS 中的 setState」中,我们简单地理解了 React 中 ...
- 深入理解 React JS 中的 setState
此文主要探讨了 React JS 中的 setState 背后的机制,供深入学习 React 研究之用. 在课程 React.js入门基础与案例开发 中,有些同学会发现 React JS 中的 set ...
随机推荐
- Attributes.Add用途与用法
Attributes.Add("javascript事件","javascript语句"); 如: this.TextBox1.Attributes.add(& ...
- 《剑指offer》面试题13—O(1)时间删除链表结点
题目:给定单向链表的头指针和某结点指针,实现函数在O(1)时间内删除指定节点. 思路:由于没有要删除结点(j结点)的前一个结点(i结点)指针,通常想法是从头开始遍历找到指定结点的前一个结点(i结点), ...
- 安装MySQL出现1045错误
安装MySQL出现1045错误 一.运行环境 MySQL mysql-5.1.26-rc-win32 操作系统:Windows 7 X64 二.问题描述 安装MySQL过程中会涉及对root密码的设置 ...
- 如何有效提升Unity Gear VR游戏性能
http://www.vr186.com/vr_news/vr_technical_area/1093.html 好的,所以你决定用 Unity 来做一个 VR 游戏,并选定了三星 Gear vr 为 ...
- Unity5自动命名Assetbundle并打包
http://www.shihuanjue.com/?p=57 using UnityEngine; using System.Collections; using UnityEditor; usin ...
- qscoj53(图的m着色问题)
题目链接:http://qscoj.cn/contest/12/problem/53/ 题意:中文题诶- 思路:n个点, 那么最多用n种颜色,所以我们可以枚举颜色种类1~n,然后再判断用 i 种颜色可 ...
- 一篇文章彻底弄懂CAS实现SSO单点登录原理
1. CAS 简介 1.1. What is CAS ? CAS ( Central Authentication Service ) 是 Yale 大学发起的一个企业级的.开源的项目,旨在为 Web ...
- djangoForm组件
https://www.cnblogs.com/jabbok/p/9273786.html 在之前学习了html form信息传递到django,然后进行处理,但是这很不方便. django有自己的组 ...
- 牛客寒假5-D.炫酷路途
链接:https://ac.nowcoder.com/acm/contest/331/D 题意: 小希现在要从寝室赶到机房,路途可以按距离分为N段,第i个和i+1个是直接相连的,只需要一秒钟就可以相互 ...
- SSE练习:单精度浮点数组求和
SSE(Streaming SIMD Extensions)指令是一种SIMD 指令, Intrinsics函数则是对SSE指令的函数封装,利用C语言形式来调用SIMD指令集,大大提高了易读性和可维护 ...