I am trying to implement sorting algorithms and build react app to display how unsorted array is changing with each iteration.
To make it visible, app has to stop for some time after every iteration and I'm trying to do this with setTimeout function and useEffect hook but it doesn't work.
Here is my component:
import { useEffect, useState } from "react" import { SortAlgorithms } from "../Utils/Sort" export default function SortingBoard(){ const [board, setBoard] = useState([10,9,8,7,6,5,4,3,2,1]) const [delay, setDelay] = useState(500) const [algorithm, setAlgorithm] = useState(() => SortAlgorithms[0]) const [isIterating, setIsIterating] = useState(false) useEffect(() => { async function sleep(){ const timer = new Promise(r => setTimeout(r, delay)); await timer } sleep() }, [board]) const handleSort = async () => { setIsIterating(true) algorithm({board, setBoard}) setIsIterating(false) } return ( <div className="bord-layout"> <div className="bord"> {board.map( (item, idx) =>{ return <h1 key={idx}>{item}</h1> })} </div> <div className="bord-options"> <select name="algorithms" onChange={e => setAlgorithm(() => SortAlgorithms[e.target.value])}> <option value={0}>Bubble Sort</option> <option value={1}>Sellection Sort</option> </select> <button disabled={isIterating} onClick={handleSort}> Sort </button> </div> </div> ) } Here are sort functions:
function BubbleSort({board, setBoard}){ for(let i = 0; i < board.length; i++){ for(let j = 0; j < board.length - 1; j++){ if(board[j] > board[j + 1]){ const temp = board[j] board[j] = board[j + 1] board[j + 1] = temp setBoard([...board]) } } } } function SelectionSort({board, setBoard}){ for(let i = 0; i < board.length; i++){ let min = i for(let j = i + 1; j < board.length; j++){ if( board[j] < board[min]){ min = j } } const temp = board[i] board[i] = board[min] board[min] = temp setBoard([...board]) } } export const SortAlgorithms = [BubbleSort, SelectionSort] In particular, it calls setTimeout on every iteration but doesn't wait for them to resolve.
Should i use useEffect and setTimeout in this case or there is other approach I can use?
forloop runs, you need to fundamentally rewrite your sorting to put the timeout in there, and use callbacks and saving state rather than a for loop. You're probably better off with a simple console.log