I am practicing react right now, doing a sorting visualization app. I am stuck with implementing the sorting function (the idea is to add some delay between iterations to make it possible to see changes in real-time).
There is in my code a class component that contains bubbleSort() method (that calls function* bSort) and render() method (that do changes when this.state.array changes on each function iteration).
It works this way: when I call bubbleSort() array of numbers (which affects rendering) changes only ones.

For example:
Here is a part from component class:
bubbleSorting = () => {
for (let i = 0; i < this.state.consequence.length ** 2; i++) {
var arr = bubbleSorting(this.state.consequence).next();
this.setState({ consequence: arr.value });
}
};
Here is below generator function:
export function *bSort (arr: number[]) {
let len = arr.length;
for (let i = 0; i < len; i++) {
for (let j = 0; j < len; j++) {
if (arr[j] > arr[j + 1]) {
let tmp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = tmp;
}
yield arr;
}
}
return arr;
};
export default bSort;
How can I refactor this part of code to make it work?
Well you can use an async / await function with an sleep function
function sleep(ms) {
return new Promise(res => setTimeout(res, ms)
}
Then you add like 100ms to wait till the page updates
bubbleSorting = async () => {
for (let i = 0; i < this.state.consequence.length ** 2; i++) {
var arr = bubbleSorting(this.state.consequence).next();
this.setState({ consequence: arr.value });
await sleep(100)
}
};
You can await for the next animation frame. But this would be a bit too fast i guess.
function nextFrame() {
return new Promise(res => requestAnimationFrame(res))
}
bubbleSorting = async () => {
for (let i = 0; i < this.state.consequence.length ** 2; i++) {
var arr = bubbleSorting(this.state.consequence).next();
this.setState({ consequence: arr.value });
await nextFrame()
}
};
nextTime will be called whenever the browser is about to repaint. Thats somewhere around 16ms