• 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。

    来源:https://www.cnblogs.com/katydids/p/10014111.html

  • 相关阅读:
    java学习--基础知识进阶第十一天--笔记
    java学习--基础知识进阶第十天--笔记
    java学习--基础知识进阶第十天--标准输入流 & 转换流 & 打印流、对象操作流 、Properties集合
    java学习--基础知识进阶第九天--笔记
    java学习--基础知识进阶第九天-- File类、字符流与字节流
    java学习--基础知识进阶第八天--笔记
    java学习--基础知识进阶第八天--异常体系&异常处理、Throwable常用方法&自定义异常、递归
    java学习--基础知识进阶第七天--笔记
    java学习--基础知识进阶第七天--HashSet集合、HashMap集合(集合遍历)
    java学习--基础知识进阶第六天--笔记
  • 原文地址:https://www.cnblogs.com/liangzhixiaolaohu/p/14402323.html
Copyright © 2020-2023  润新知