[英]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:单击该按钮时,需要执行以下操作:
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.