DanH
DanH

Reputation: 3802

Ramifications of React setState directly modifying prevState?

I was looking at some example react code (in the antd docs), and I noticed they have code that is equivalent to:

this.setState(prevState => { prevState.name = "NewValue"; return prevState; });

This looks a bit naughty, but does it actually break anything? Since it's using the arrow function it's not breaking the ordering of changes being applied even if React batches them up in the background.

Of course setState is intended to expect a partial state so there might be performance side effects there as it might try to apply the whole state to itself.

edit: (in response to @Sulthan)

The actual code is this:

handleChange(key, index, value) {
  const { data } = this.state;
  data[index][key].value = value;
  this.setState({ data });
}

n.b. data is an array, so its just being copied by reference then mutated.

It's actually completely wrong as its not even using the arrow function to get the latest state.

It comes from the editable table example here: https://ant.design/components/table/

Upvotes: 3

Views: 845

Answers (1)

Sulthan
Sulthan

Reputation: 130102

Your example can be also rewritten as:

this.setState(prevState => {
    prevState.name = "NewValue"
    return "NewValue";
});

When a function is passed to the state the important thing is not to mutate the passed parameter and return the new state. Your example fails both.

...prevState is a reference to the previous state. It should not be directly mutated. Instead, changes should be represented by building a new state object based on the input from prevState...

(from setState)

I am not sure whether it was ever possible to use setState like in your example but looking into the change log I really doubt it.

Upvotes: 3

Related Questions