Home > front end >  `setState` doesn't update array
`setState` doesn't update array

Time:11-04

I have a component that renders an array with .map() and a button that setState the shuffled version of it.

I'm trying to have it update every time I click that button but it doesn't.

const Home: NextPage = () => {
  const [random, setRandom] = useState(students);

  function randomize() {
    const shuffle = students.sort(() => 0.5 - Math.random());
    setRandom(shuffle);
  }

  return (
    <>
      <main className="container mx-auto flex min-h-screen flex-col items-center justify-center p-4">
        <h1 className="text-6xl font-bold">This week&apos;s seat</h1>

        <button onClick={randomize}>Shuffle</button>

        {/* Seatings */}
        <div className="seatbox">
          {random.map((student) => (
            <Seat key={student}>{student}</Seat>
          ))}
        </div>
      </main>
    </>
  );
};

I tried to log the random state, it got updated it just doesn't get rendered probably.

The Seat component is made with styled-components and the students array is an array of strings with the students name like this

const students = [
  "Joe",
  "Jason"
]

CodePudding user response:

This sorts the array:

const shuffle = students.sort(() => 0.5 - Math.random());

But... it sorts the array in place and returns a reference to that same array. Since the reference equality hasn't changed (an array is a kind of object after all), React has no way to know that the state has been updated. It doesn't do any kind of deep compare, just an equality comparison for whatever is sent to it.

If you duplicate the array just before sorting (so as to not mutate it), the newly sorted array will be a new object reference and won't be "equal" to the previous state:

const shuffle = [...students].sort(() => 0.5 - Math.random());
  • Related