I am trying to build a sorting algorithm visualizer that represents the values of an array as rectangles with different heights corresponding to each element’s value. It’s supposed to show each step of the algorithm’s process, with every loop occurring after a second has passed. However, whenever the web page loads, the array is already sorted. I want to make it so that after every second, the position of the rectangle being sorted changes so that each step of the sorting algorithm is being shown. My code is below:
index.tsx
import SortingAlgorithm from '@/components/sorting-algorithm'
import { Inter } from 'next/font/google'
const App: React.FC = () => {
return(
<div className='headerContainer'>
<h1 className='header'>ππ
Ύπππ
Έπ
½π
Ά π
°π
»π
Άπ
Ύππ
Έππ
·π
Ό π
π
Έπππ
°π
»π
Έππ
΄π</h1>
<SortingAlgorithm />
</div>
)
}
export default App;
sorting-algorithm.tsx
import { Inter } from 'next/font/google'
import React, { useState, useEffect } from 'react'
const SortingAlgorithm: React.FC = () => {
const [arr, setArr] = useState<number[]>([3, 1, 2, 5, 4]);
//Selection sort
while (arr != arr.sort()) {
useEffect(() => {
for (let i = 0; i < arr.length; i++) {
const loop = setTimeout(() => {
let minIndex: number = i;
for (let j = i + 1; j < arr.length; j++) {
if (arr[j] < arr[minIndex]) {
minIndex = j;
}
}
let temp: number = arr[i];
arr[i] = arr[minIndex];
arr[minIndex] = temp;
}, 1000);
return() => clearTimeout(loop);
}
}, []);
}
return arr.map<JSX.Element>((keys) => (
<div className='barsContainer'>
<svg className='bars'>
<rect height={keys * 25} width={100 - (arr.length * 10)} x={arr.indexOf(keys) * 53} y={0}/>
</svg>
</div>
))
}
export default SortingAlgorithm;
I’ve already implemented setTimeout
inside the for loop containing the sorting algorithm. I thought it would be the perfect solution to my problem, yet it seems that it doesn’t alter the speed at which the for loop loops. I’ve also tried playing around with the syntax, though that doesn’t really seem to make a difference. A point in the right direction at least would be greatly appreciated.
2
Answers
I figured out what to do based off of another Stackoverflow post. I've decided to post my code below just in case someone else had the same issue and this is the first thing they find.
}, []);
Here is a sample implementation for a full solution.
Below, please see this minimal example with a counter that demonstrates in its most basic form what you are trying to accomplish:
A few notes on hooks:
as
if
,while
, etc. A hook must be executed every single timeyour react function executes in order for them to work properly. If
you check your dev console, you may see React warning or erroring
about this.
setState
to know when to update your component. Since you never callsetArr
, your component never updates. See setStateConsider reading the full documentation on hooks so you can develop a complete understanding of their intended uses.