首页 > 解决方案 > 如何在 setState 之后在 React 中强制立即更新 DOM(即提交)?

问题描述

我有一个带有按钮的 React 组件(显示“加载数据”)和几个子组件,每个子组件都采用一组数据并将它们绘制成图形,并且渲染速度相对较慢(Highcharts)。

单击该按钮时,需要执行以下操作:

  1. 将文本从“加载数据”更改为“加载...”(基于 this.state.isLoadingData)
  2. 将空数组传递给子组件(以便它们清除最后加载的数据)
  3. 向服务器发送请求以获取数据
  4. 收到响应后,将服务器数据传递给子组件(以便他们绘制新数据图表)

这是按如下方式完成的:

// Make button show "Loading Data..."
this.setState( { isLoadingData: true } ); // I want DOM to update immediately after this
// Clear charts in child components
this.setState( { data: [] }, this.loadDataFromServer ); // This causes child components to re-render (a bit slow)

this.loadDataFromServer 将执行以下操作:

// Chart the new data in child components
this.setState( { data: newData, isLoadingData: false });

最终发生的是按钮和子组件同时更新,这会在按钮从“加载数据”变为“加载...”时引入可察觉的 UI 延迟。在我看来,尽管在每个 setStates 之后都会调用 render()(console.log() 证明了这一点),但 React 会批处理实际的 DOM 提交,以便仅在两个 setStates 都完成后才更新 DOM。

有什么建议么?

请注意,setStates 本身的批处理不是问题,因为我什至尝试过这个,但对主要问题没有任何影响:

this.setState( { isLoadingData: true }, () => {
  this.setState( { data: [] }, this.loadDataFromServer )
}

标签: javascriptreactjsdom

解决方案


通过实验,我发现使用 a setTimeout(即使延迟为 0)会导致 React 以我想要的方式提交给 DOM。IE

this.setState( { isLoadingData: true } );
setTimeout(() => {
  this.setState( { data: [] }, this.loadDataFromServer )
}, 0);


推荐阅读