I'm trying to make an algorithm-visualisation app, and am now working on insertion sort. It takes a data array, and a setData() hook as parameters, and sets the state every few milliseconds (for the user to see the gradual sorting effect):
const delay = (ms) => new Promise((r) => setTimeout(r, ms)) // helper func
async function insertionSort(data, setData) {
const inputArr = [...data]
let n = inputArr.length
for (let i = 1; i < n; i++) {
await delay(200) // pause
// Choosing the first element in our unsorted subarray
let current = inputArr[i]
// The last element of our sorted subarray
let j = i - 1
while (j > -1 && current < inputArr[j]) {
await delay(200) // pause
inputArr[j + 1] = inputArr[j]
j--
}
inputArr[j + 1] = current
setData(inputArr)
}
setData(inputArr)
}
export default insertionSort
The sorting function is called in the main app, and the data is mapped to DOM elements like so:
const [data, setData] = useState([72,22,131,30,402]) //array to be sorted
return (
<div className="App">
<button
onClick={async () => {
await insertionSort(data, setData)
}}>
Insertion Sort
</button>
data.map((val, i) => (
<div key={`${val}${i}`}>{val}</div>
))
</div>
)
The issue is that the DOM elements don't re-render on each setData() call. The sorting function works correctly if I comment out the await command. Other times I ran into this issue was usually because the keys given weren't unique to the DOM elements, but am very certain they are in this case.
Forcing a separate state update ( like adding a number to the array through another button ) does indeed refresh the dom elements, and shows the array being sorted. This leads me to believe that the state must be updating, just not re-rendering?