0

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>
  );
}
2
  • pass the collection state as dependency to useEffect. hope that works, and why are you putting setCollection inside useEffect? Commented Nov 2, 2022 at 9:55
  • I am just initially populating collection this way for testing purposes. Commented Nov 2, 2022 at 9:58

1 Answer 1

3

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>
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.