浅入深出setState(上篇)

Part one - setState点燃引擎

setState点燃引擎

这是一个React组件实现组件可交互所需的流程,render()输出虚拟DOM,虚拟DOM转为DOM,再在DOM上注册事件,事件触发setState()修改数据,在每次调用setState方法时,React会自动执行render方法来更新虚拟DOM,若是组件已经被渲染,那么还会更新到DOM中去。
这个过程,setState就像一个点燃引擎的打火石,发动了React核心的调度层,而后直至渲染层的改变。react

Part two - setState是异步的

刚接触React的同窗,对React的setState的使用偶尔会有一些偏颇,出现一些意料以外的状况。
好比:git

onClickForReset=()=>{
    this.setState({value: []});
    // 此刻立马取this.state作一些同步操做
    console.log(this.state.value);
}

或者是github

increateCount(){
    this.setState({count: this.state.count + 1});
    this.setState({count: this.state.count + 1});
    this.setState({count: this.state.count + 1});
}

咱们能够看一个如今的例子:
https://codesandbox.io/s/qqy9n5o2m9性能优化

https://codesandbox.io/s/qqy9n5o2m9

setState比较熟练的同窗能够跳过这一段代码,可是有些刚学会使用React的同窗常常会犯这个错误,一开始我只能粗暴地说:异步

  1. setState是异步的,不会当即改变state的值。
  2. 屡次setState调用生成的效果会合并。
  3. 第二个参数能够是一个回调函数。
  4. setState能够接受一个函数(例子改动)

后来我逐渐也在想下面这两个问题,如今这篇文章试图尽可能弄清的两件事:函数

  1. 为何要把setState设计成异步的,原因是什么,解决了什么问题,有什么好处?
  2. 如何实现异步的setState,总体原理是怎样的,有没有什么特殊的骚操做?

咱们能够本身也想想,下面留给你们一片空白区。😝性能

<div style="background:#fff;width:100%;height:500px;margin-bottom:30px;"></div>优化

好,咱们带着这两个问题和本身的猜测,试图一探究竟。this

Part three - 为何要异步

简单的来讲:在批量屡次的更新中,延缓到最后合并渲染是有好处的。spa

万剑归宗

  1. 保证内部的一致性:首先,我想咱们都赞成推迟并批量处理重渲染是有益并且对性能优化很重要的,不管 setState() 是同步的仍是异步的。那么就算让 state 同步更新,props 也不行,由于当父组件重渲染(re-render )了你才知道 props。
  2. 在批量屡次的更新中,延缓到最后合并渲染是有好处的。这一点,和咱们熟知的防抖动函数的出发点相似,咱们广泛认为在许多状况下在同一时间段,频繁setState触发渲染,连续同步效率很低,对性能有极大损耗。

咱们来看下setState引起组件的更新过程就知道了:

setState引起组件的更新过程

每一次setState若是都引起一次组件更新,走完一圈生命周期,实在是有点粗糙和浪费,生命周期函数为纯函数性能应当还可以接受,但是render函数内返回的虚拟DOM去作比较这个就比较费时间了。

直观的感觉是,React将多个setState产生的修改放在一个队列里,缓一缓,攒在一块儿,等待时机,以为差很少了再引起一次更新过程。这样,在每次更新过程当中,会把积攒的setState结果合并,作一个merge的动做,节省render触发的频率。
这样,对于开发者而言,能够在同步代码中随意多行调用setState函数而不用担忧重复setState重复render的问题。

而后,老是被你们误用不理解的也是这一点,因此后来,setState方法的第二个参数慢慢被进入你们的视野了,做为回调函数能够再次拿到新的this.state值。

再后来,一个setState函数的隐藏功能进入了你们的视野,那就是,setState能够接受一个函数做为参数。

更多: https://github.com/facebook/react/issues/11527#issuecomment-360199710

Part four - 怎么实现异步

在此以前,咱们来看一个例子…可能会颠覆你对setState的认识

咱们能够直接打开在线案例:https://codesandbox.io/s/vq1nqkvyw5

setState真的是异步吗

提问:实际运行结果是怎么样的?好吧如今下

Part five - 彩蛋:setState真的是异步吗?

咱们上面一个例子告诉咱们:

No! 多是同步 超出React生命周期和React代理事件以外都是同步

预知后事如何,请看下半篇。

相关文章
相关标签/搜索