Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

`setState` doesn't update array

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.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

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"
]

>Solution :

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());
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading