0

I am building a react app using react-d3-graph. I have a state like this:

data: {
        nodes: [{"id": "8", "color": "red"}],
      },

By clicking one node of the graph I want to change its color from red to yellow. So I make a callback to the root component where I initialize the state. The callback in the root component looks like this:

var color = {...this.state.data}
color.nodes[0].color = 'yellow';
this.setState({color});

If I console.log the state, the value has been changed but the node in the app remains red. However, these changes happen after any following action in the app.

Konstantinos Ks
  • 79
  • 1
  • 2
  • 9

1 Answers1

0

You should never modify React state directly, but have to do it immutably like:

var modifiedData = {...this.state.data}; // shallow copy of data
var modifiedNodes = [...this.state.data.nodes] // shallow copy of nodes array
var modifiedNode = {...this.state.data.nodes[0]} // shallow copy of node you are trying to change the color of
modifiedNode.color = 'yellow'; // changes color of a copy of the original node (not the original node itself, ensuring you aren't modifying the original React state directly)
modifiedNodes[0] = modifiedNode; // modifies the copy, for same reason
modifiedData.nodes = modifiedNodes; // modifies the copy, again for same reason
this.setState({data: modifiedData });

Also, not sure why you had "this.setState({color});", on the last line. If you have state as "data: { nodes: [{"id": "8", "color": "red"}], }," then you should have 'this.setState({data: modifiedData });', like I have it above. And again, you shouldn't modify state directly like you are doing it in 'color.nodes[0].color = 'yellow';'. This is directly modifying state because 'var color = [...this.state.data]' only takes a shallow copy, meaning any nested arrays and objects (since they arrays and objects are reference types in Javascript) are not deeply copied. You have to deeply copy them like I did above.

More on why you shouldn't modify state directly:

https://daveceddia.com/why-not-modify-react-state-directly/

Why can't I directly modify a component's state, really?

Aiyaz N.
  • 31
  • 5