I have a simple React class showing this.state.progress
(a number) and this state can be updated via updateProgress(progress)
function.
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
progress: 0,
}
}
updateProgress = (progress) => {this.setState({progress}); };
render() {
let {progress} = this.state;
return <h1>{progress}</h1>;
}
}
I have a compute intensive function myHeavyFunc
, for which I need to show the progress bar. I call updateProgress
function I mentioned above using the loop variable inside myHeavyFunc
.
myHeavyFunc = async (updateProgress) => {
let loopLength = 1000000;
updateProgress(0);
for(let i=0; i<loopLength; i++) {
// some processing happens here
updateProgress((i+1)/loopLength);
}
}
What happens is that state gets updated, and I can confirm that by console logging progress in the setState
callback, but the component doesn't re-render until the very end. However, if I include a small sleep of 1ms, then the re-render happens, progress updates (obviously with a huge loss in time, which I do not prefer).
JSFiddle here. Here I run myHeavyFunc
on clicking the progress number. You can see that when await sleep(1)
is commented, onClick
finishes in a second, but does NOT show progress. It does not even change for any subsequent clicks. On the other hand, if it is not commented, I get the progress updates, but it just takes forever to complete!
I am aware that React shall batch the updates for performance reasons, but in my case, I can't even see one update happen till the whole loop finishes. Also, please note that I am NOT looking for a synchronous setState
function, but I need re-rendering (atleast on the progress element alone) after the state is set. I am fine if it drops a few progress updates due to batching, but I do expect it to show progress.
Is there a way to run myHeavyFunc
in a non-blocking manner while updating the progress in the UI? What is the right way to update progress of compute intensive functions in React?
from React updating progress from a compute intensive function using setState
No comments:
Post a Comment