Search code examples
javascriptarraysreactjssortinguse-state

Sort method is not working with useState() in React


I put onClick() event on element and try to change on UI new data but it fails. podaciLjubimci in console.log() returns me new state with new data based on countLike but nothing happens on UI.

Why does array change with new data and send me in console.log() but setState() did not render component?

Code:

const [podaciLjubimci, setState] = useState([
  { id: 1, naziv: "naziv", pol: "Muski", starost: "junuor", mesto: "Beograd", isLike: false, countLike: 1, },
  { id: 2, naziv: "naziv", pol: "Muski", starost: "junuor", mesto: "Beograd", isLike: false, countLike: 12, },
  { id: 3, naziv: "naziv", pol: "Muski", starost: "junuor", mesto: "Beograd", isLike: false, countLike: 12, },
  { id: 4, naziv: "naziv", pol: "Muski", starost: "junuor", mesto: "Beograd", isLike: false, countLike: 5, },
  { id: 5, naziv: "naziv", pol: "Muski", starost: "junuor", mesto: "Beograd", isLike: false, countLike: 2, },
  { id: 6, naziv: "naziv", pol: "Muski", starost: "junuor", mesto: "Beograd", isLike: false, countLike: 7, },
  { id: 7, naziv: "naziv", pol: "Muski", starost: "junuor", mesto: "Beograd", isLike: false, countLike: 22, },
  { id: 8, naziv: "naziv", pol: "Muski", starost: "junuor", mesto: "Beograd", isLike: false, countLike: 9, },
]);

const nepopularni = () => {
  setState(podaciLjubimci.sort((a, b) => a.countLike - b.countLike));
  console.log("sort", podaciLjubimci);
};

Solution

  • With the below code:

    setState(podaciLjubimci.sort((a, b) => a.countLike - b.countLike))
    

    you are mutating the state data because sort() method sorts the elements of an array in place and returns the sorted (same reference, not new) array. And that's the reason your console log shows you sorted data but it does not re-render the component.

    To sort the state data without mutating the original data, you need to shallow copy the array before sorting.

    An example:

    setState([].concat(podaciLjubimci).sort((a, b) => a.countLike - b.countLike))
    

    PS: There are many ways to shallow copy the array. For example, you can use .slice(), spread syntax, concat(), or .map().