Imagine I got an array of promise (12 promise total), I want to render the progress of the promise has resolved on page like: 1/12, 2/12, 3/12 something like that. So I got the idea of how to do it from this answer here: link
I successfully calculated the progressNum or the percentage, and able to console.log them.
The problem is when I try to use setState to set the progressNum, its only show 12/12 when all the promise have resolved. Or render some random num like 4/12 and then 12/12 after, but I want to render something like go from 1/12, 2/12, 3/13 ... 12/12.
Im able to console.log the progress correctly
And I know setState is async, so I try to use react ref to manipulate the element. But didn't get any luck too.
My code so far:
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> )
}
I also try 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> )
}
}