React shouldComponentUpdate() is called even when props or state for that component did not change

The purpose of shouldComponentUpdate is to indicate if render should be called. In your case some parent component has rendered and indicated it wanted to also render an instance of your child component.

shouldComponentUpdate is your opportunity to short-circuit that render and say 'don't bother, nothing changed down here'.

Now, to your question, "why was it even called since nothing changed"? React does not compare the old and new props itself. You can get a mixin to do it for you, (ie. PureRenderMixin), but by default React just lets the render run.

The reason React doesn't do the comparison itself is for a couple reasons. Firstly, the performance savings of skipping render may be negligible compared to analyzing props and state. Since React's render mechanism is already optimized to avoid unnecessary DOM manipulation it can just assume the component needs to update and expect reasonable performance. Secondly, doing the comparison is not exactly straight-forward. Is your prop a primitive?, an Immutable?, an array?, a complex object?, will a deep compare be necessary?

React's model is "We will render everything asked by default. If you want something to opt-out for performance, then go ahead and tell us by implementing shouldComponentUpdate".


React automatically calls shouldComponentUpdate, it is triggered before the re-rendering process starts (in this case of your parent component.) So naturally it is called frequently.

The default implementation of this function returns true so to stop the re-render you need to return false here:

  shouldComponentUpdate(nextProps, nextState) {
    console.log(nextProps, nextState);
    console.log(this.props, this.state);

    return false;  
  }

Advanced Concerns, React page

So, in summary, React avoids carrying out expensive DOM operations required to reconcile subtrees of the DOM by allowing the user to short circuit the process using shouldComponentUpdate,


shouldComponentUpdate() is called everytime:

  • the props are updated by every re-render of the parent component. This includes all scenario's where re-render takes place with exactly the same prop values.
  • the state is updated by a call to setState() (the only way allowed by react). This includes all scenario's where the value of state is exactly the same.

Sometimes it can be useful to let the re-render cycle go through, even though the new value is exactly the same as the old value. E.g. when your component receives a user ID (could be unchanged) through props, and fetches new messages from somewhere and puts them in state.

Also, 'shouldComponentUpdate()`, as a separate method to check for changes and only update if something changed, makes for nice maintainable code:

  • make a first version without shouldComponentUpdate(), and ensure that the same set of props and state lead to the same outcome being rendered.
  • add and debug shouldComponentUpdate()

It is relatively easy to debug a 'state machine' that takes input (state and props) and renders output. It is much harder to debug a machine that manages state changes.

Tags:

Reactjs