前端框架从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的使用和深入理解的更多相关文章

  1. React中的setState到底发生了什么?

    https://yq.aliyun.com/ziliao/301671 https://segmentfault.com/a/1190000014498196 https://blog.csdn.ne ...

  2. 3.React中的setstate的几个现象

    转载segfault 上面的一篇文章,https://segmentfault.com/a/1190000014498196 1.在同一个方法中多次setState是会被合并的,并且对相同属性的设置只 ...

  3. react中this.setState的理解

    this.setState作用? 在react中要修改this.state要使用this.setState,因为this.state只是一个对象,单纯的修改state并不会触发ui更新.所以我们需要用 ...

  4. React中的state与props的再理解

    props可以看做是 property 的缩写的复数,可以翻译为属性,类似于HTML 标签的自定义属性.在大多数React教程里讲 state 和 props 主要的区别在于 props 是不可变的, ...

  5. React中this.setState是同步还是异步?为什么要设计成异步?

    在使用react的时候,this.setState为什么是异步呢? 一直以来没有深思这个问题.昨天就此问题搜索了一下. react创始人之一 Dan Abramovgaearon在GitHub上回答了 ...

  6. react 中的 setState

    语法:setState(newState [,callback]) 1.只要有入门基础的同学都知道 setState({...}) 是更新组件中的 state 内容 2.但是,setState 是异步 ...

  7. React中的setState(obj)

    1.setState(obj)  只能浅merge obj,对于复杂对象结构的不行 比如:  this.state = {   data:{  idx:1 }   }   this.setState( ...

  8. 从源码的角度再看 React JS 中的 setState

    在这一篇文章中,我们从源码的角度再次理解下 setState 的更新机制,供深入研究学习之用. 在上一篇手记「深入理解 React JS 中的 setState」中,我们简单地理解了 React 中 ...

  9. 深入理解 React JS 中的 setState

    此文主要探讨了 React JS 中的 setState 背后的机制,供深入学习 React 研究之用. 在课程 React.js入门基础与案例开发 中,有些同学会发现 React JS 中的 set ...

随机推荐

  1. 简单运行Lua代码

    http://blog.csdn.net/hamenny/article/details/4420522

  2. ASP.NET Core Web API + Angular 仿B站(三)后台配置 JWT 的基于 token 的验证

    前言: 本系列文章主要为对所学 Angular 框架的一次微小的实践,对 b站页面作简单的模仿. 本系列文章主要参考资料: 微软文档: https://docs.microsoft.com/zh-cn ...

  3. 翻转链表中相邻的k个节点

    示例: 输入:1->2->3->4->5 k=2 输出:2->1->4->3->5 k=3输出:3->2->1->4->5 Py ...

  4. 「干货」常用的10个网络DOS命令,菜鸟学了变高手

    1 ping命令 1命令格式 ping 主机名 ping 域名 ping IP地址 如图所示,使用ping命令检查到IP地址210.43.16.17的计算机的连通性,该例为连接正常.共发送了四个测试数 ...

  5. 百度网盘不限速!VIP视频免费看!这两款插件被无数人安利!

    今天给给位推荐两款,我一直在使用的浏览器插件,简直爆炸!全网VIP视频随意看,所有网页上的视频,你想要的全部都能下载! 这两款插件堪称日常必备插件,只要你使用浏览器,就一定需要下面这些插件功能:快速下 ...

  6. go系列(1)- linux下安装go环境

    安装GO 打开安装包下载地址,查看linux下go的最新版本 https://golang.google.cn/dl/ 经查看go的最新版本为go1.11.4.linux-amd64.tar.gz 右 ...

  7. JS异常捕获和抛出

    try...catch 用来异常捕获(主要适用于IE5以上内核的浏览器,也是最常用的异常捕获方式) 使用onerror时间捕获异常,这种捕获方式是比较古老的一中方式,目前一些主流的浏览器暂不支持这种 ...

  8. jmeter diff测试(调用JAR包处理)

    1.准备接口数据(对比字段,即json数据中需要提取的key对应的值进行对比) 2.配置获取EXCEL数据 3.新建线程,并建两个http请求,分别用于请求新旧接口 4.提取需要对比的内容 5.赋值变 ...

  9. Codeforces 1142B(倍增)

    1.先预处理出在循环中某数前面的数是谁. 2.读入a数列时贪心选取最晚的父亲. 3.链上倍增预处理二进制祖先. 4.对于每个位置,预处理第n-1个祖先位置最早要从哪里开始,技巧上再顺手与前一位的最早位 ...

  10. Hive_Hive的管理_CLI方式

    Hive的启动方式- CLI- Web UI- 远程服务启动方式 (1)hive命令行的交互模式,进入hive: hive; hive --service cli; hive -S;(设置Hive静默 ...