0

I get an object as response from a get.

Now I assign the object to a state var (object) like this:

 this.setState({editData: response.data})

Is there a way to change the values within this object?

I thought about something like this:

this.setState({editData.[var]: [value]})

thanks

Felix
  • 5,452
  • 12
  • 68
  • 163

1 Answers1

3

Firstly you have to remember that you should never mutate state object directly. So first you shold make a copy of state object and mutate the copy. Then set this copy as state. You can use spread syntax to achieve it:

this.setState((prevState) => ({editData: {...prevState.editData, [var]: value}}));

Here is working example showing that source object is not mutated:

let state = {
  editData: {
    age: 22
  }
};

let age = "age";
let stateCopy = {editData: {...state.editData, [age]: 100}};

console.log(state);
console.log(stateCopy);
Bartek Fryzowicz
  • 6,464
  • 18
  • 27
  • Since you're changing state based on state, you must use the callback with `setState`, you cannot pass it the object directly. So: `this.setState(prev => ({editData: {...prev.editData, [var]: value}));` – T.J. Crowder May 24 '17 at 12:52
  • Because `setState` queues an asynchronous process. There's a fair bit about this in the discussion of `setState` [in the documentation](https://facebook.github.io/react/docs/react-component.html#setstate); in particular, see the example starting with *"This form of setState() is also asynchronous, and multiple calls during the same cycle may be batched together."* In the above, since it makes a shallow copy of `editData`, that's using current state to create new state, and so you have to use the callback. – T.J. Crowder May 24 '17 at 13:00
  • Ok, but i think it would make a difference if I set new property value based on previous value (e.g. `editData.property: prevEditData.property + 1`) but if we want to override property with totally new value that is not computed from previous value it doesn't matter – Bartek Fryzowicz May 24 '17 at 13:06
  • It matters, because *other* properties of `editData` may be getting changed by other `setState` calls; but your code is queuing a call with what may be (by the time it's applied) stale information. Even if you know there aren't any others being changed as of when you write your call, it lays a maintenance trap. – T.J. Crowder May 24 '17 at 13:08
  • 1
    Good answer. And thanks again to you for your comments on my deleted answer. I'm dashing out, but I'm going to post a question about the subordinate property thing. I suspect the answer is we have to create a copy of `editData` as you are above, but I want to be sure. – T.J. Crowder May 24 '17 at 13:18