12

Initial state:

this.state = {
  someVar: true
};

What if I have a code that set state value the same as the old one:

this.setState({
  someVar: true
});

Does the second snippet execute? And does it cost the performance if it does execute and run many times?

Ramon Balthazar
  • 3,907
  • 3
  • 25
  • 34
Pho Huynh
  • 1,497
  • 3
  • 13
  • 23

4 Answers4

10

Does the second snippet execute? And does it cost the performance if it does execute and run many times?

Yes and yes. However, there are two approaches to preventing this from happening.


Extending with PureComponent

Normally when writing a React Component you would write:

class MyComponent extends React.Component {

If you want React to perform a shallow comparison on the new and old props and state, you would write instead:

class MyComponent extends React.PureComponent {

This is the simpler approach. More info from the official documentation, here.


Manually checking on shouldComponentUpdate()

You can always perform this logic yourself and tell React when to ignore a re-render with the shouldComponentUpdate() lifecycle method.

shouldComponentUpdate(nextProps, nextState) {
  if(this.state.someVar === nextState.someVar) return false;
  return true;
}

In the above example, the component will not re-render if someVar is the same across renders. However, any other update to another state or prop variable will trigger a re-render.

More info from the official documentation, here.

Community
  • 1
  • 1
Chris
  • 57,622
  • 19
  • 111
  • 137
  • If there are more than 1 state (someVar, someVar2,...), `shouldComponentUpdate` cannot solve the problem though. Because this will prevent component update when only one state remains the same. – Pho Huynh Oct 19 '17 at 07:43
  • @PoBéo, you could always add those variables in your logic. Like `if(this.state.someVar === nextState.someVar || this.state.someVar2 === nextState.someVar2) return false;`. Alternatively, you could compare the whole state objects (`this.state` and `nextState`). See [here](https://stackoverflow.com/a/1144249/2030321) for how to do that. – Chris Oct 19 '17 at 07:44
  • How does this apply to functional components? – Vadorequest Feb 04 '21 at 09:23
1

Yes, it does if you don't have any comparison regarding state in your shouldComponentUpdate.

You can do this by default if your component extends PureComponent instead. You can read more here.

Daniel Andrei
  • 2,654
  • 15
  • 16
  • Note OP that the `shouldComponentUpdate` is only *shallow* for objects. Make sure to read that link documentation before just extending it. – Jayce444 Oct 19 '17 at 07:20
  • 1
    Pure component would use shallow comparison – Sulthan Oct 19 '17 at 07:21
  • Shallow states should only be used anyway. If not, the object itself should be recreated. For e.g, this.setState({...existingThingy, {key: newValue}}); – Adrian Bartholomew Sep 19 '18 at 13:21
0

Setting state will only set new values, there is no comparison with the previous state. shouldComponentUpdate is then invoked to decide whether render should take place or not.

Note that it returns true by default.

Sulthan
  • 128,090
  • 22
  • 218
  • 270
0

Actually you can call multiple setStates and React may batch multiple setState() calls into a single update for performance. But keep in mind that this will be async (setState updates doc).

As for setting the same state, all other answers are correct. SetState will execute even when new value is equal.

Andy Theos
  • 3,216
  • 1
  • 15
  • 24