前端框架从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. webpack 4 基础知识点梳理

    目录 webpack安装 webpack配置文件 webpack核心概念 entry output loader plugins sourceMap webpack-dev-server 跨域 &am ...

  2. vuex实现购物车功能

    购物车功能描述: 1. 点击+,-按钮,“已选:xx件”随之增减 2. checkbox选中时,当前项的已选数量增加到头部“已选择xx件”中,未选中时数量不计入 代码: 服务端 node+koa+ko ...

  3. Codeforces Round #269 (Div. 2) A,B,C,D

    CodeForces - 471A 首先要有四个数相等,然后剩下两个数不同就是Bear,否则就是Elephant. #include <bits/stdc++.h> using names ...

  4. laravel 视图调用方法并传递参数

    视图层 route 中文 路由 <a href="{{route('cc',array('id'=>11111))}}">446454</a> 路由层 ...

  5. C++函数返回值与引用

    对于函数的返回值,看似简单,但并非如此,比如: int func(int a);该函数会返回一个int型,如果进行一个调用int result=func(3);会发生什么情况? 首先,func将返回值 ...

  6. 一文解析总结Java虚拟机内存区域模型

    最近抽空看了一点<深入理解Java虚拟机>,本篇文章主要来总结一下Java虚拟机内存的各个区域,以及这些区域的作用.服务对象以及其中可能产生的问题,作为大家的面试宝典. 首先我们来看一下J ...

  7. Metabolic and gut microbial characterization of obesity-prone mice under high-fat diet (文献分享一组-赵容丽)

    题目:高脂饮食下易肥胖小鼠的代谢和肠道微生物特性研究 Metabolic and gut microbial characterization of obesity-prone mice under ...

  8. IT兄弟连 JavaWeb教程 EL表达式中的运算

    EL语言支持算符运算符.关系运算符和逻辑运算符等,以完成常见的数据处理操作.所有的运算符说明见表7.2. 表2  El表达式中的运算符

  9. one jar(转)

    http://blog.csdn.net/kabini/article/details/1598827

  10. Qt 进程和线程之一:运行一个进程和进程间通信

    Qt提供了对进程和线程的支持.本节讲述了怎样在Qt应用程序中启动一个进程,以及几种常用的进程间通信方法.如果对进程和线程的概念不是很了解,可以看我的另一篇博客:[多进程和多线程的概念. 设计应用程序时 ...