1

In react, is there a reason why someone would want to set the state of a variable by assignment instead of calling setState(...)

Example:

// accessing state var directly
this.state.myVar = 'changed state'
// instead of calling setState
this.setState({myVar: 'changed state'})

To me this seems like an anti-pattern. But maybe there's a good explanation why sometimes it's necessary?

David Ly-Gagnon
  • 411
  • 4
  • 15

2 Answers2

3

It's necessary, because React has to know wether this.state is considered mutated. There is no dirty-checking in React. The state object is considered dirty when this.setState is called, and no further comparisons are made to its previous state. This answer might help explain this in more detail: Why is React's concept of Virtual DOM said to be more performant than dirty model checking?

Community
  • 1
  • 1
Eelke
  • 2,267
  • 1
  • 22
  • 26
  • So if I update a state var by doing: this.state.myVar ='changed var', the state object won't be considered dirty I assume? That would be a reason why someone would want to do this? – David Ly-Gagnon Sep 01 '15 at 23:46
  • I think you should avoid mutating the state directly, it avoids confusing code and "why won't this update!?!" :) – Eelke Sep 02 '15 at 07:55
  • Yes, that's what I think to. I was just curious to know if there are good reasons to do this. – David Ly-Gagnon Sep 03 '15 at 06:18
0

Setting (mutating) the state directly will work in this case: this.state.myVar = 'changed state'
However, it should be avoided according to the React docs:

NEVER mutate this.state directly, as calling setState() afterwards may replace the mutation you made. Treat this.state as if it were immutable.

The main problem with mutating the state is that it prevents some of the React lifecycle methods from working. For example, React's shouldComponentUpdate() method is often used to speed up the app when dealing with a large number of components. The method allows you to skip re-rendering a component if the state has been updated:

// Return false if you want to skip the `render()` method
shouldComponentUpdate: function(nextProps, nextState) {
  return this.state.myVar === nextState.myVar;
}

The above will not work if you are mutating the state. this.state.myVar and nextState.myVar references are the same and therefore the above will always return true.

Piotr Berebecki
  • 7,428
  • 4
  • 33
  • 42