admin管理员组

文章数量:1199962

I have component which receives data from other file and setting into state:

const [sortedPlans, setSortedPlans] = useState(
    data.Plans.sort((a, b) => b.IndustryGrade - a.IndustryGrade)
  );//data is from external file

After setting the state, sorting the data and rendering the initial screen, I have function that sorts the sortedPlans whenever it is called:

const sort = (event) => {
    console.log(event);
    const newArr = sortedPlans.sort((a, b) => {
      return b[event] - a[event];
    });
    console.log(newArr);
    return setSortedPlans(newArr);
  };

The problem is that this is never triggering a re-render of the component. I want when I set the new state to be able to see it inside the jsx. Why when I console.log(newArr) the results are correctly sorted but this setting of the state not triggering re-render? Here is the sandbox:

=/src/App.js

I have component which receives data from other file and setting into state:

const [sortedPlans, setSortedPlans] = useState(
    data.Plans.sort((a, b) => b.IndustryGrade - a.IndustryGrade)
  );//data is from external file

After setting the state, sorting the data and rendering the initial screen, I have function that sorts the sortedPlans whenever it is called:

const sort = (event) => {
    console.log(event);
    const newArr = sortedPlans.sort((a, b) => {
      return b[event] - a[event];
    });
    console.log(newArr);
    return setSortedPlans(newArr);
  };

The problem is that this is never triggering a re-render of the component. I want when I set the new state to be able to see it inside the jsx. Why when I console.log(newArr) the results are correctly sorted but this setting of the state not triggering re-render? Here is the sandbox:

https://codesandbox.io/s/charming-shape-r9ps3p?file=/src/App.js

Share Improve this question asked Apr 6, 2022 at 12:41 Borislav StefanovBorislav Stefanov 7313 gold badges19 silver badges44 bronze badges 5
  • 6 React will only re-render if you set a new value. sortedPlans.sort sorts the array in-place however and returns the same array. – Felix Kling Commented Apr 6, 2022 at 12:48
  • This is a similar questions stackoverflow.com/questions/61478050/… – rMonteiro Commented Apr 6, 2022 at 12:49
  • @FelixKling So basically I am setting the same thing as React assumes that this is the same array – Borislav Stefanov Commented Apr 6, 2022 at 12:49
  • 2 It is the same array: var arr = [3,2,1]; console.log(arr === arr.sort());. React will only re-render if necessary, i.e. if values change. React doesn't know that you mutated this array. That's why in React you usually create copies of mutable values before you mutate them. – Felix Kling Commented Apr 6, 2022 at 12:52
  • This is about object's reference. Take a look at this issue github.com/facebook/react/issues/19181 – Jeff Pal Commented Jan 11, 2023 at 20:22
Add a comment  | 

1 Answer 1

Reset to default 23

Here you go: Codesandbox demo.

You should first make a shallow copy of the array you want to modify. Then set that array as the new state. Then it re-renders the component and you are able to filter like you want.

  const sort = (event) => {
    console.log(event);
    //shallow copying the state. 
    const newArr = [...sortedPlans];

    //modifying the copy
    newArr.sort((a, b) => {
      return b[event] - a[event];
    });
    console.log(newArr); //results here are correctly sorted as per event
    
    //setting the state to the copy triggers the re-render.
    return setSortedPlans(newArr);
  };

本文标签: javascriptreact setState() not triggering rerenderStack Overflow