在 React 中,setstate
方法有时是异步的,有时是同步的,具体取决于它们的使用方式和环境。
当我们调用时做出反应setstate
方法,React 将新状态合并到组件的状态队列中,并在未来的某个时间点更新组件的状态。 此更新过程是异步的,即不能保证它会存在setstate
状态在调用后立即更新,而是将状态更新推迟到下一个渲染周期。 在本例中,setstate
该方法返回一个promise
对象,但该对象不包含任何有用的信息。
但是,当setstate
当直接调用方法时,更新过程是同步的,而不是在事件处理程序、异步或生命周期函数中调用的。 在这种情况下,React 会立即更新组件的状态,并在更新后立即执行重新渲染。 在本例中,setstate
该方法不返回任何信息。
需要注意的是,React 中异步更新状态的机制可以提高性能并优化页面渲染速度,因为它允许 React 在正确的时间批量更新组件状态,从而避免过度渲染和浏览器性能问题。 如果我们需要在更新状态后立即执行某些操作,则可以使用它setstate
方法的函数或生命周期函数componentdidupdate
来实现它。 例如:
jscopy codeclass mycomponent extends react.component ; handleclick() => )render()这里this.handleclick()}increment
setstate
该方法接受 ** 函数作为第二个参数,在状态更新完成后调用该函数,并将更新后的状态作为参数传递。 在此功能中,您可以执行状态更新后需要立即执行的任何操作,例如输出调试信息、发送网络请求等。
2023.04.19 更新。如果在 setstate 之后无法直接获取 state 的值。 SetState 是异步的,React 的内部机制可以检测到它;在 React 无法检测到的地方,例如原生事件
addeventlistener
setinterval
settimeout
,setstate 是同步的 setstate 的更新不是简单的异步或同步,这实际上与调用时的环境有关。
在 Composition Event 和 Lifecycle 挂钩(ComponentDidUpdate 除外)中,SetState 为"异步"之;在原生事件和 settimeout 中,setstate 是同步的,可以立即获取更新的值批量更新
不是逐个同步执行 setstate,而是将它们一个接一个地排队,然后最终一起执行。 在 Synthetic Events 和 Lifecycle Hooks 中,当 setstate 更新队列时,它会存储合并状态 (object.)。assign)。因此,之前设置的键值将在以后被覆盖,并且更新将只执行一次。
异步现象的原因
setstate 的“异步”并不意味着它是在内部通过异步实现的
其实执行过程本身是与**同步的,但是合成事件和生命钩子函数的调用顺序是在更新之前,导致合成事件和钩子函数中无法立即获取到更新后的值,形成了所谓的“异步”。当然,你可以通过在第二个参数 setstate(partialstate, callback) 中使用回调来获取更新后的结果。
setState 并不是真正的异步,它只是看起来是异步的。 在源代码中,使用 isbatchingupdates 来确定这一点
SetState 调用流程:
调用此名称setState(newstate)将新状态 newstate 存储在待处理队列中,判断是否在 Batch Update(isBatchingUpdates is true)isBatchingUpdates=true,将组件保存在 dirtycomponents 中,经过异步更新过程,合并操作,延迟更新;isBatchingUpdates=false。 遍历所有 dirtyComponents,调用 UpdateComponent,更新待处理状态或 props
为什么要修改它状态无效
SetState 实质上是通过排队机制实现状态更新。 当 setstate 被执行时,需要更新的状态会被合并并放入状态队列中,而不是立即更新状态,队列机制可以批量更新状态。
如果您不直接通过 setstate 修改它state,那么这个状态就不会放到状态队列中了,下次我们调用 setState 合并状态队列时,会忽略之前直接修改过的状态,这样我们就无法合并,实际上并没有更新你想要的状态。
参考文档: