user10477345
user10477345

Reputation:

React hooks useState/setState not working after sorting the array and passing it

I have React app and I am using React hooks:

  const [companies, setCompanies] = useState([]);

I am fetching the data and 'companies' is getting filled with data. I also have another button for sorting the data by NetIncome:

 const sortByIncome = e => {
    const el = document.getElementById("sort-selectbox");
    const arr = companies.sort((a, b) => (a.NetIncome > b.NetIncome ? -1 : 1));
    console.log(arr);
    setCompanies(arr);
  };

The problem is that setCompanies does not re-renders. In the console.log I can see that array is sorted correctly and even if I console.log(companies) I can see that it is also sorted. But noting happens in the interface. Also if I type the same code:

const sortByIncome = e => {
    const el = document.getElementById("sort-selectbox");
    const arr = companies.sort((a, b) => (a.NetIncome > b.NetIncome ? -1 : 1));
    console.log(arr);
    setCompanies([]);
  };

but pass to setCompanies empty array it immediately works and displays nothing (I have render function that gets companies as param). So why it is not working with passing arr? Is it because I am passing the same array but just sorted?

Upvotes: 7

Views: 2552

Answers (2)

user6612182
user6612182

Reputation:

The value of the hook-variable companies inside the function sortByIncome will always be the initial value of your hook ([]) and will never receive the new value set by using setCompanies.

A solution to your problem is to wrap your function sortByIncome in a useCallback hook with the hook-variable companies as a dependency. This will ensure that the function always uses the current value of companies.

const sortByIncome = React.useCallback(e => {

   // Using `companies` will always result in the current value

}, [companies]);

useCallback documentation

Upvotes: 0

mbojko
mbojko

Reputation: 14669

Here:

    const arr = companies.sort((a, b) => //...

Array.prototype.sort sorts array in place, that is, mutates the original object. The reference doesn't change, and the mutation doesn't get noticed. Do instead

    const arr = [...companies].sort((a, b) => //...

Upvotes: 12

Related Questions