寄语:问题比答案更重要
建议自己先有个思考的过程,有了自己的答案或者疑问再看解析进行对比。
目前解析在逐步添加中,也可以跳转链接查看。
在代码中调用setState 函数之后,React 会将传入的参数对象与组 件当前的状态合并,然后触发调和过程(Reconciliation)。经过调和 过程,React 会以相对高效的方式根据新的状态构建React 元素树 并且着手重新渲染整个UI 界面。
在React 得到元素树之后,React 会自动计算出新的树与老树的节 点差异,然后根据差异对界面进行最小化重渲染。在差异计算算法中, React 能够相对精确地知道哪些位置发生了改变以及应该如何改变, 这就保证了按需更新,而不是全部重新渲染。
如果在短时间内频繁setState。React 会将state 的改变压入栈中, 在合适的时机,批量更新state 和视图,达到提高性能的效果。
假如所有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 不能保持一致性,会在开发 中产生很多的问题。
解析或答案仅供参考。