score:2

Accepted answer

it has to do with react batching state updates in event handlers

please check this link

i tried to solve it with changing sort to be a generator function and iterator pattern with useeffect hook. -> my solution

its not a polished solution. but maybe it can help you come up with some ideas :)

if you cannot access the link here is the code

app.js

import sort from "./sort";
import "./styles.css";
import { useeffect, usestate, useref } from "react";

const delay = (ms) => new promise((r) => settimeout(r, ms)); // helper func

const initialarray = [72, 22, 402, 131, 30];

const initialdata = { data: initialarray, sortstep: -1 };

export default function app() {
  const [state, setstate] = usestate(() => initialdata);
  const iterator = useref();

  const runsort = async () => {
    if (state.sortstep >= 0) {
      const { value, done } = iterator.current.next();
      if (!done) { // here since sort is not done.we go to next sortstep
        await delay(1000);
        setstate((s) => ({ ...s, data: value, sortstep: s.sortstep + 1 }));
      } else {
        // sorting is done. maybe reset things up.
      }
    }
  };

  const startsort = () => {
    iterator.current = sort(initialarray);
    setstate((s) => ({ ...s, data: initialarray, sortstep: 0 }));
    // here we initiate sort by setting the sortstep to zero
  };

  useeffect(() => {
    runsort();
  }, [state.sortstep]); // whenever ${sortstep} changes we try to sort again it to next step untill the sorting is complete

  return (
    <div classname="app">
      
      <button onclick={startsort}>insertion sort</button>

      {state.sortstep >= 0 && <h4>step: {state.sortstep}</h4>}

      {state.data.map((val, i) => (
        <div key={`${val}${i}`}>{val}</div>
      ))}
    </div>
  );
}

sort.js

function* sort(data) {
  const inputarr = [...data];
  let n = inputarr.length;
  for (let i = 1; i < n; i++) {
    // 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]) {
      inputarr[j + 1] = inputarr[j];
      j--;
    }
    inputarr[j + 1] = current;
    yield inputarr;
  }
}

export default sort;

score:0

use anonymous function when you are setting the state based on to previous state

setdata((state, props) => {
   //do something here 
});

Related Query

More Query from same tag