关注本站公众号,
获取永久访问授权码
扫码关注,回复『刷题』即可.
~技术问答题~
返 回

No.836 React setState 调用之后发生了什么?是同步还是异步?

题目描述~ 略...

寄语:问题比答案更重要

建议自己先有个思考的过程,有了自己的答案或者疑问再看解析进行对比。

目前解析在逐步添加中,也可以跳转链接查看。

(1)React 中setState 后发生了什么

在代码中调用setState 函数之后,React 会将传入的参数对象与组 件当前的状态合并,然后触发调和过程(Reconciliation)。经过调和 过程,React 会以相对高效的方式根据新的状态构建React 元素树 并且着手重新渲染整个UI 界面。

在React 得到元素树之后,React 会自动计算出新的树与老树的节 点差异,然后根据差异对界面进行最小化重渲染。在差异计算算法中, React 能够相对精确地知道哪些位置发生了改变以及应该如何改变, 这就保证了按需更新,而不是全部重新渲染。

如果在短时间内频繁setState。React 会将state 的改变压入栈中, 在合适的时机,批量更新state 和视图,达到提高性能的效果。

(2)setState 是同步还是异步的

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

setState 并不是单纯同步/异步的,它的表现会因调用场景的不同而 不同。在源码中,通过isBatchingUpdates 来判断setState 是先 存进state 队列还是直接更新,如果值为true 则执行异步操作, 为false 则直接更新。

异步:在React 可以控制的地方,就为true,比如在React 生命 周期事件和合成事件中,都会走合并操作,延迟更新的策略。 同步:在React 无法控制的地方,比如原生事件,具体就是在 addEventListener 、setTimeout、setInterval 等事件中,就只能 同步更新。

一般认为,做异步设计是为了性能优化、减少渲染次数: setState 设计为异步,可以显著的提升性能。如果每次调用setState 都进行一次更新,那么意味着render 函数会被频繁调用,界面重新 渲染,这样效率是很低的;最好的办法应该是获取到多个更新,之后 进行批量更新;

如果同步更新了state,但是还没有执行render 函数,那么state 和props 不能保持同步。state 和props 不能保持一致性,会在开发 中产生很多的问题。

解析或答案仅供参考。

关于作者

zz_jesse 专注前端

掘金 我的开源项目

公众号@前端技术江湖

一个可以帮开发者成长的公众号前端面试题库更新通知前端学习资料、干货文章

技术交流群

交流中成长大厂内推机会