Home > Mobile >  My React state does not update using useState hook with a slightly complexer object
My React state does not update using useState hook with a slightly complexer object

Time:08-25

In my React app I purposely combined several arrays in one state using a useState hook. These arrays represent visual objects that I would like to keep "managed" together to ensure that that re-renderings of my application are visually consistent.

While testing I tried to change a property of some objects of my first array. updatedElements reflects the update properly (clearly shown by my console-log). However, updating my useState state does not work. The array elements does not change at all.

Here is the relevant code:

const updatedElements: VisualDiagramElementData[] =
  visualData.elements.map((element: VisualDiagramElementData) =>
    element.id === id
      ? { ...element, selected: true }
      : { ...element, selected: false }
  );

console.log(updatedElements);

setVisualData({
  elements: updatedElements,
  connectors: visualData.connections,
  connections: visualData.connections,
});

What am I missing / doing wrong? Any help is highly appreciated!

CodePudding user response:

When updating a state property based on its previous value, the callback argument of the state setter should be used. Otherwise you may use stale state values.

https://reactjs.org/docs/state-and-lifecycle.html#state-updates-may-be-asynchronous
https://reactjs.org/docs/hooks-reference.html#functional-updates

It should be:

setVisualData((visualData)=>({
    elements: visualData.elements.map(/*Your map callback*/),
    connectors: visualData.connections,
    connections: visualData.connections,
}));

CodePudding user response:

I would go with what is recommended in the React docs - split them out into multiple state variables: https://reactjs.org/docs/hooks-faq.html#should-i-use-one-or-many-state-variables.

Depending on how you trigger the state updates will determine whether re-render occurs multiple times or not. See this answer for more details on how the batching works: https://stackoverflow.com/a/53048903/6854709

Also take note of the comment by aprillion:

Note from github.com/facebook/react/issues/10231#issuecomment-316644950 - This is implementation detail and may change in future versions.

CodePudding user response:

Eventually, it worked by using the "callback argument of the state setter". I revised / reviewed my entire code and I modified all my state setters accordingly. Now, everything works like a charm. Thank you very much again for your help, especially to Nice Books.

  • Related