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 ...
随机推荐
- Eclipse如何查看接口实现类快捷键
1.找到要打开的接口类 2.双击接口名选中 3.按Ctrl+T打开接口实现类 以List接口为例,如下所示
- ThinkPHP3.2.3中,查询语句中in的使用方法。
//删除分类 public function del(){ $cid = I('get.cid'); $cate = M('category')->field('cid,pid')->se ...
- mysql 事务 存储过程 函数
一:事务: 开启一个事务可以包含一些SQL语句,这些sql语句要么同时成功, 要么一个都别想成功, 称之我事务的原子性 事务用于将某些操作的多个SQL 作为原子性操作, 一旦有某一个出现错误, 即可以 ...
- DOM学习笔记(三)DOM元素的访问、修改与事件
访问 HTML 元素等同于访问节点,使用的是document对象下的数个getElement方法,然后再对返回的元素(或元素列表)进行具体内容的访问和修改,或者响应对应的事件是操作 一些 DOM 对象 ...
- L2-023 图着色问题 (25 分)vector
图着色问题是一个著名的NP完全问题.给定无向图,,问可否用K种颜色为V中的每一个顶点分配一种颜色,使得不会有两个相邻顶点具有同一种颜色? 但本题并不是要你解决这个着色问题,而是对给定的一种颜色分配,请 ...
- 51nod 1413
思路: 直接在串里找个最大的值就好了: #include <cstdio> #include <cstring> #include <cstdlib> #inclu ...
- laravel MVC分布及数据库配置
laravel MVC分布 M app\Http\Middleware V resources\views C app\Http\Controllers 数据库配置 目录 config\datab ...
- Window 10 Alt Tap 切换窗口,设置成Windows 7风格
升级了Windows 10 以后,切换窗口非常的难受.新版的窗口切换的图标变成了窗口预览了,这总让我一瞬间找不到要去的窗口,所以我打算切换成Windows 7 的小图标风格. Windows + R ...
- 你了解SVN, CVS等版本控制器吗?
版本控制器SVN, CVS是两种版本控制器, 需要配套相关的SVN, CVS服务器, SCM是xcode里面配置版本控制的地方, 版本控制的原理就是A和B同时开发一个项目, A写完当天的代码之后把代码 ...
- Linux之expect非交互式功能
我在上一篇博文linux之SSH密钥认证 提过ssh之间的相互认证,但是每次使用ssh登录到其它服务器还是要输入密码的. expect是用于提供自动交互的工具,自动连接被管理的服务器,不需要手动输入密 ...