Sar*_*ran 6 javascript setstate progress-bar reactjs
我有一个简单的 React 类显示this.state.progress(一个数字),这个状态可以通过updateProgress(progress)函数更新。
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>;
}
}
Run Code Online (Sandbox Code Playgroud)
我有一个计算密集型函数myHeavyFunc,我需要显示进度条。我updateProgress使用内部的循环变量调用上面提到的函数myHeavyFunc。
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>;
}
}
Run Code Online (Sandbox Code Playgroud)
发生的情况是状态被更新,我可以通过控制台记录setState回调中的进度来确认这一点,但组件直到最后才会重新渲染。但是,如果我包含 1毫秒的小睡眠,则重新渲染发生,进度更新(显然时间损失很大,我不喜欢)。
JSFiddle在这里。在这里,我myHeavyFunc点击进度号运行。你可以看到 whenawait sleep(1)被评论,onClick在一秒钟内完成,但不显示进度。它甚至不会因任何后续点击而改变。另一方面,如果没有评论,我会收到进度更新,但需要很长时间才能完成!
我知道 React 会出于性能原因批量更新,但就我而言,在整个循环完成之前,我什至看不到一个更新发生。另外,请注意,我不是在寻找同步 setState函数,而是在设置状态后需要重新渲染(至少仅在进度元素上)。如果由于批处理而丢失一些进度更新,我很好,但我确实希望它显示进度。
有没有办法myHeavyFunc在更新 UI 进度的同时以非阻塞方式运行?在 React 中更新计算密集型函数的进度的正确方法是什么?
我猜问题出在浏览器重画上。通常,浏览器每秒重绘 60 帧。在您的情况下,您要求浏览器执行超出其能力的绘画。我建议使用requestAnimationFrame而不是 for 循环,以不断更新 DOM。requestAnimationFrame将处理浏览器执行下一次重绘之前要调用的函数。
let i = 0
let loopLength = 1000;
let myHeavyFunc = (updateProgress) => {
updateProgress((i+1)/loopLength);
i++;
if (i < loopLength) {
window.requestAnimationFrame(() => myHeavyFunc(updateProgress));
}
}
Run Code Online (Sandbox Code Playgroud)
工作演示https://jsfiddle.net/gdq5ouat/5/
| 归档时间: |
|
| 查看次数: |
927 次 |
| 最近记录: |