例如,某个组件的初始状态为{loading: true, setup: true}
,并且在更改状态时如下所示:
this.setState({
loading: false,
setup: false
})
在真实DOM上是否有机会loading
是false
而setup
仍然是true
?据我所知(如果我错了,请纠正我),通过VDOM进行更新的过程如下:
diff queue
requestAnimationFrame
)的速度批处理diff queue
中的所有更改。然后按顺序将所有变异应用于DOM。由于我们将所有补丁按顺序应用到DOM,因此我假设会有一段时间loading: false
和setup: true
?
答案 0 :(得分:4)
由于不能保证对象属性的顺序,所以也不能保证setState的顺序。同样,setStates内部的所有状态都会更新一次,因为它们存在于object中。因此,在您的示例中,状态loading
和setup
都立即被更新。但是我们不能说loading
首先,setup
最后的顺序。我们不能说一种状态为true
,另一种状态为false
。两种状态都立即更新为false
,但不能保证其顺序(对象中属性的顺序)。
浏览器会两次绘制和布局(随着我们更改两个状态)吗?
状态更新后,浏览器将重新绘制。在浏览器重新绘制之前,两种状态都已受到影响。渲染钩子将被调用两次,分别是初始状态和更新状态。
如果要将一个状态设为true
,将另一个状态设为false
,则可以使用如下回调:
this.setState({
loading: false
}, () => {
setTimeout(() => {
this.setState({
setup: false
})
}, 5000) // setup to false after 5 seconds
答案 1 :(得分:1)
是否有一段时间
loading
是false
而setup
是true
?
不,我敢肯定 setState
没有机会被拆分成单独的更新的机会,这些更新可以单独传递给DOM。
这种方式行不通。
首先:在一次fn调用中,VDOM会同时更新两项更改。
第二:不会使用“部分准备好”的更新来更新DOM。当某些(并行)进程尚未准备就绪时,差异(由于Fiber)会延迟DOM更新的片段。