lgwebdream/FE-Interview

Day99:React 中 setState 后发生了什么?setState 为什么默认是异步?setState 什么时候是同步?

Opened this issue · 3 comments

每日一题会在下午四点在交流群集中讨论,五点 Github、交流群同步更新答案

扫描下方二维码,收藏关注,及时获取答案以及详细解析,同时可解锁800+道前端面试题。

每日一题会在下午四点在交流群集中讨论,五点 Github、交流群同步更新答案

一、React中setState后发生了什么

在代码中调用setState函数之后,React 会将传入的参数对象与组件当前的状态合并,然后触发所谓的调和过程(Reconciliation)。

经过调和过程,React 会以相对高效的方式根据新的状态构建 React 元素树并且着手重新渲染整个UI界面。

在 React 得到元素树之后,React 会自动计算出新的树与老树的节点差异,然后根据差异对界面进行最小化重渲染。

在差异计算算法中,React 能够相对精确地知道哪些位置发生了改变以及应该如何改变,这就保证了按需更新,而不是全部重新渲染。

二、setState 为什么默认是异步

假如所有setState是同步的,意味着每执行一次setState时(有可能一个同步代码中,多次setState),都重新vnode diff + dom修改,这对性能来说是极为不好的。如果是异步,则可以把一个同步代码中的多个setState合并成一次组件更新。

三、setState 什么时候是同步

在setTimeout或者原生事件中,setState是同步的。

异步加个引号,这个问题可能会更好一些哈哈

为什么是异步?因为执行setState会创建一个调度任务,但react的调度器本身就是异步的宏任务,所以这里也会表现为异步,调度是一个发布订阅模式,用的MessageChannel

为什么有时候是同步?因为如果在执行setState后,如果当前执行上下文为空,则会取消已经注册的调度任务,但这只是legacy、blocking 模式下的情况,concurrent模式永远是异步