Home > Enterprise >  React state variable does not trigger rerender when sorted
React state variable does not trigger rerender when sorted

Time:11-02

I want to implement a sortable table in React. I store the table's content as an array in a state variable using the useState hook. Now, when I sort the array and update the content state variable, I would expect the table to re-render since I updated the state. Unfortunately, that is not the case and the table does not display the sorting. Here is a simplified version of my issue. When I click on the table's header field "Name" I trigger the sorting and update of the state, but it does not rerender. Any idea what I am missing?

import { useState, useEffect } from 'react';

function App() {

  type Entry = {
    id: number;
    name: string;
  };

  const [collection, setCollection] = useState<Entry[]>([]);

  useEffect(()=> {
    // just initially populating collection with data for testing purposes
    setCollection([{id:1, name:"Ben"}, {id:2, name:"John"}, {id:3, name:"Anna"}])
  }, [])

  const byName = (a: Entry, b: Entry) => {
    let x = a.name.toLowerCase();
    let y = b.name.toLowerCase();
    if (x < y) {return -1;}
    if (x > y) {return 1;}
    return 0;
  }

  return (
    <div>
      <table>
        <tr id="head">
          <th>Id</th>
          <th onClick={() => setCollection(collection.sort(byName))}>Name</th>
        </tr>
        {collection.map((val, index) => 
          <tr id={index.toString()}>
            <td>{val.id}</td>
            <td>{val.name}</td>
          </tr>
        )}
      </table>
    </div>
  );
}

CodePudding user response:

The sort function sorts in place and returns the same reference, so you are mutating state, not updating it.

Do

<th onClick={() => setCollection([...collection].sort(byName))}>Name</th>
  • Related