Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

I added lifecycle method to my React component

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

    return false;  
  },

My issue is that this method is called on the component even when nextProps, and nextState, is exactly the same as the current props and state. When I compare the console.log statements for nextProps and this.props the are exactly the same. Same with the state.

So why is shouldComponentUpdate called?

It is called whenever I change the state of the parent component. But none of the props or state are changing on the actual component. So why is it called?

fyi, I am using React with Meteor

Further Clarification:

I am wondering why the function shouldComponentUpdate is being called in the first place. None of the state or props of that component are changing. But the state of the parent component is changing.

like image 968
Nearpoint Avatar asked Apr 07 '16 20:04

Nearpoint


2 Answers

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".

like image 67
LodeRunner28 Avatar answered Sep 19 '22 03:09

LodeRunner28


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,

like image 39
omarjmh Avatar answered Sep 20 '22 03:09

omarjmh