前端框架从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. java的Set, List, Map简单介绍

    Set, List, Map Set和List,Map都是集合,Set和List都是继承于Collection接口,而Map不是. 1.Map(映射) :Map是以key,Value的形式存储数据的映 ...

  2. LeetCode: 620 Not Boring Movies(easy)

    题目: X city opened a new cinema, many people would like to go to this cinema. The cinema also gives o ...

  3. JAVA企业级开发-session,cookie(13)

    一. jsp jsp: java server pager        .java动态生成网页的一门技术 使用servlet生成网页时候遇到的问题,为什么使用jsp? 在servlet里面书写htm ...

  4. 读取MySQL数据表字段信息

    TP5句式 $fieldinfo = Db::query('SHOW FULL COLUMNS FROM '.$table);//查出数据表所有字段信息Field 字段Comment 字段注释

  5. thinkphp5.0 cache数据缓存机制

    use think\cache; public function index(){ //Cache::get('name')获取缓存,如果name值不存在则返回false: if (Cache::ge ...

  6. [3dmax教程] 人物+骨骼+蒙皮+动画教程

    人物+骨骼+蒙皮+动画完整教程选准备好一个人,做人的方法我在这里就不做了,大家可以学都用poser来做一个.  在大腿里建立4根骨骼! 在前视图中移动如图所示位置! 做一段简单的骨骼向前伸的动画,做4 ...

  7. mysql之SQL入门与提升(四)——终结篇,函数

    一.SQL Aggregate (聚合)函数 SQL Aggregate 函数计算从列中取得的值,返回一个单一的值. AVG() - 返回平均值 COUNT() - 返回行数 FIRST() - 返回 ...

  8. Unrecogized font family ‘Ionicons’ 在ios上报错,android正常

    解决方法: react-native link react-native-vector-icons 很多模块都需要link一下

  9. js截取文件名不带后缀

    利用正则表达式是匹配后缀名 一般文件后缀都为.xxx,也就是说从尾部匹配的话首先是字母,接着应该有一个. 那么我们就开始写正则表达式 利用在线工具 方便我们编写边测试 一般都是小写字母,所以我们用[a ...

  10. 快速理解JavaScript面向对象编程—原型

    总的来说js语言就是门面向对象编程的语言,对象这个概念几乎贯穿了整个js的学习. 对象 创建对象两种方法:(若要生成对象实例必须调用构造函数) 1.var obj = {name:"jer& ...