基础 - state - 图1

代码中涉及到的关键词理解:

一次setState更新流程(代码):
基础 - state - 图2
React事件系统:
基础 - state - 图3

知识点:

Q:**state**是同步,还是异步?
答:了解底层,batchUpdate批量更新,如何打破批量更新。


Q:类组件中的 setState 和函数组件中的 useState 有什么异同?
相同点:

  • 首先从原理角度出发,setState和 useState 更新视图,底层都调用了 scheduleUpdateOnFiber 方法,而且事件驱动情况下都有批量更新规则。

不同点

  • 在不是 pureComponent 组件模式下, setState 不会浅比较两次 state 的值,只要调用 setState,在没有其他优化手段的前提下,就会执行更新。但是 useState 中的 dispatchAction 会默认比较两次 state 是否相同,然后决定是否更新组件。
  • setState 有专门监听 state 变化的回调函数 callback,可以获取最新state;但是在函数组件中,只能通过 useEffect 来执行 state 变化引起的副作用。
  • setState 在底层处理逻辑上主要是和老 state 进行合并处理,而 useState 更倾向于重新赋值。

精选评论

  1. componentDidMount中多次调用this.setState也是开启了批量更新,走的同一个事件驱动。
  2. 若无批量更新,则多次 setState 会让逻辑多停留在js运行层面,阻塞了浏览器绘制。
  3. react 16.14 对应的是DOMPluginEventSystem.js 这个文件, isBatchingEventUpdates 这个针对的是 react17以前 batchedUpdates 的实现。
    react17之后的batchedUpdates 实现是基于 lane 模型实现的 “Automatic batching”,卡颂链接

    1. setState底层执行过程:调用setState->计算优先级expirationTime->更新调度,调和fiber->合并state,执行render->commit更新真是DOM->执行回调函数
    2. 类组件对setState限制:1.pureComponent这一新的类,通过判断state和props判断是否需要更新,节省了virtual dom环节,提高性能。2.shouldComponentUpdate(preState,preProps)生命周期函数,通过返回布尔值来决定是否执行更新。
    3. setState原理:1.enqueueSetState :就是创建一个 update ,然后放入当前 fiber 对象的待更新队列中,最后开启调度更新。2.batchUpdates:通过isBatchingEventUpdates标识开启batch更新。unstable_batchedUpdates:异步环境手动开启batch更新 flushSync:提升setState优先级。
    4. setState与useState不同点:1.非pureComponent不会进行浅比较,只要setState就会更新。useState会进行浅比较。2.setState有回调获取修改后的state,useState只能通过useEffect获取dispatch执行后的副作用。3.setState倾向与合并,useState是替换。