简体   繁体   English

如何在 setState 之后在 React 中强制立即更新 DOM(即提交)?

[英]How can I force an immediate DOM update (i.e. commit) in React after setState?

I have a React component with a button (displaying "Load Data") and several child components that each take an array of data and graph them and are relatively slow to render (Highcharts).我有一个带有按钮的 React 组件(显示“加载数据”)和几个子组件,每个子组件都采用一组数据并将它们绘制成图形,并且渲染速度相对较慢(Highcharts)。

The button, when clicked, needs to do the following:单击该按钮时,需要执行以下操作:

  1. Change the text from 'Load Data' to 'Loading...' (based on this.state.isLoadingData)将文本从“加载数据”更改为“加载...”(基于 this.state.isLoadingData)
  2. Pass empty array to the child components (so they clear the last loaded data)将空数组传递给子组件(以便它们清除最后加载的数据)
  3. Send request to server to get data向服务器发送请求以获取数据
  4. When response received, pass server data to the child components (so they chart the new data)收到响应后,将服务器数据传递给子组件(以便他们绘制新数据图表)

This is done as follows:这是按如下方式完成的:

// 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 will do the following: this.loadDataFromServer 将执行以下操作:

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

What ends up happening is that the button and child components are updated at the same time and this introduces a perceptible UI delay for when the button goes from "Load Data" to "Loading...".最终发生的是按钮和子组件同时更新,这会在按钮从“加载数据”变为“加载...”时引入可察觉的 UI 延迟。 It appears to me that although render() is called after each of the setStates (console.log() proves this), React batches the actual DOM commits so that the DOM is only updated after both of the two setStates are done.在我看来,虽然在每个 setStates 之后都会调用 render()(console.log() 证明了这一点),但 React 会批处理实际的 DOM 提交,以便仅在两个 setStates 都完成后才更新 DOM。

Any suggestions?有什么建议么?

Note that the batching of the setStates themselves are not the issue as I have even tried this without any effect on the main issue:请注意,setStates 本身的批处理不是问题,因为我什至尝试过这个,但对主要问题没有任何影响:

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

By experimentation I have found that using a setTimeout (even with 0 delay) results in React committing to the DOM in the way I want.通过实验,我发现使用setTimeout (即使延迟为 0)会导致 React 以我想要的方式提交给 DOM。 ie IE

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

why not set the data to empty array and set isLoadingData to true simultaneously.Then the next step: this.loadDataFromServer just like this为什么不将数据设置为空数组并同时将isLoadingData设置为true。然后下一步:this.loadDataFromServer就像这样


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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 AngularJS:在长时间运行的循环中强制DOM更新(即进度指示器) - AngularJS: force DOM update during long-running loop (i.e. progress indicator) 如何强制在JSP(即不是PHP)上重新加载缓存的css文件? - How can I force a cached css file to be reloaded on a JSP (i.e. not PHP)? 如何强制 setState 执行更改? - How can I force setState to perform changes? 强制IE中的链接在Firefox中打开 - Force a link in I.E. to open in Firefox 如何在ajax调用后刷新页面,但还要传递参数? 即未完全刷新 - How can I refresh the page after an ajax call but passing parameters as well? I.e. not full refresh dom更改后如何使用react hooks强制更新 - How to force update after dom change with react hooks 如何动态更新我的CSS,即我想让用户选择字体大小,bckground颜色 - How can I dynamically update my CSS i.e. I want to give user an option of selecting font size, bckground color 如何强制jQuery UI Selectmenu出现在jQuery模式窗口的上方(即前面)? - How do I force jQuery UI Selectmenu to appear above (i.e. in front of) a jQuery modal window? 我如何在 React 的卸载组件中设置状态 - how can I setState in unmount Component in React React:如何强制状态在功能组件中更新? - React: how can I force state to update in a functional component?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM