假设我有一个promise数组(总共12个promise),我想在页面上呈现已解决的promise的进度,例如:1/12、2/12、3/12等。所以我从这个答案中得到了做法:链接。
我成功地计算了progressNum或百分比,并可以console.log它们。
问题在于,当我尝试使用setState设置progressNum时,只有在所有promise都得到解决时才会显示12/12。或者随机渲染一些数字,例如4/12,然后是12/12,但我想呈现的是从1/12,2/12,3/13 ... 12/12的内容。 我能够正确地console.log进度。 不能正确地渲染。
我知道setState是异步的,所以我尝试使用react ref来操作元素。但也没有什么运气。
到目前为止,我的代码是:
我也尝试使用Ref。
我成功地计算了progressNum或百分比,并可以console.log它们。
问题在于,当我尝试使用setState设置progressNum时,只有在所有promise都得到解决时才会显示12/12。或者随机渲染一些数字,例如4/12,然后是12/12,但我想呈现的是从1/12,2/12,3/13 ... 12/12的内容。 我能够正确地console.log进度。 不能正确地渲染。
我知道setState是异步的,所以我尝试使用react ref来操作元素。但也没有什么运气。
到目前为止,我的代码是:
class App extends Component {
state = {
progress: 0,
};
handleResize = async () => {
...
// imgFiles is an array 12 File object
this.allProgress(imgFiles.map(this.resizeImg));
...
};
allProgress(promArray) {
let progress = 0;
promArray.forEach((p) => {
p.then(()=> {
progress += 1;
console.log(`${progress}/12`);
this.setState({ progress });
});
});
return Promise.all(promArray);
}
// I use Jimp package to resize the img, and then return promise
resizeImg = imgFile => new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onloadend = () => {
Jimp.read(reader.result)
.then(async (jimpImg) => {
const normalImg = await this.resizeMain(jimpImg, true,
imgFile.name);
const largeImg = await this.resizeMain(jimpImg, false,
imgFile.name);
resolve([normalImg, largeImg]);
})
.catch(reject);
};
reader.readAsArrayBuffer(imgFile);
});
render() {
return (
<div>
<p>{this.state.progress}</p>
<button onClick={this.handleResize} >Resize</button>
</div> )
}
我也尝试使用Ref。
class App extends Component {
state = {
progress: 0,
};
indicator = React.createRef();
changeProgress = (num) => {
this.indicator.current.innerText = `${num}/12`;
};
...
allProgress(promArray) {
let progress = 0;
promArray.forEach((p) => {
p.then(()=> {
progress += 1;
console.log(`${progress}/12`);
// the only logic that I changed:
this.changeProgress(progress);
});
});
return Promise.all(promArray);
}
...
render() {
return (
<div>
<p ref={this.indicator} />
<button onClick={this.handleResize} >Resize</button>
</div> )
}
}