Maximus S
Maximus S

Reputation: 11095

Should updating props re-render the entire component?

Let's say I have a CookingClass component that gets initialized like this.

let teachers = makeTeachers(["Amber", "Jason", "Lily"])
let students = makeStudents(["Hopper"])

<CookingClass
  teachers={teachers}
  students={students}
/>

One of the teachers dropped out:

let newTeachers = makeTeachers(["Amber", "Jason"])

<CookingClass
  teachers={newTeachers}
/>

It will make the entire component re-render. I am not sure whether React only calculates the diff and efficiently re-renders it or I must use shouldComponentUpdate to take care of it myself.

More real-world example might be implementing a Google map where there are a million markers and you want to replace one of the markers.

Upvotes: 0

Views: 454

Answers (3)

Cory Danielson
Cory Danielson

Reputation: 14501

Based on your sample code, the component will re-render everytime.

You should use the react-redux (documentation) bindings to "connect" the component to the store.

// ConnectedCookingClass.js
import { connect } from 'react-redux';
import CookingClass from './CookingClass';

const mapStateToProps = (state) => {
  return {
    teachers: state.teachers,
    students: state.students
  };
};

const ConnectedCookingClass = connect(mapStateToProps)(CookingClass);

export default ConnectedCookingClass;

Then use this component elsewhere like so:

// OtherComponent.js
import ConnectedCookingClass from './ConnectedCookingClass';

const OtherComponent = React.createElement({
  render() {
    return (
      <div>
        <ConnectedCookingClass />
      </div>
    );
  }
});

The react-redux bindings will do some smart things for you, like only re-rendering the component when the props returned by mapStateToProps are actually different than their previous value (via a shallowEqual comparison), so you should try to only return values here, no functions. Functions should be returned in mapDispatchToProps.

The default implementation of shouldComponentUpdate in react-redux will return true when:

  1. ALWAYS if the component is a "pure" component (aka stateless-function)
  2. When the props have been updated manually (after componentWillReceiveProps called)
  3. When the store has changed and the new props are different than the old props.

Here's what that looks like from the source code:

shouldComponentUpdate() {
  return !pure || this.haveOwnPropsChanged || this.hasStoreStateChanged
}

Upvotes: 1

webdeb
webdeb

Reputation: 13211

The real DOM Rendering is completely handled by React with very efficient innerHTML inserts and only for changes in the new data structure of your application VirtualDomTree.

shouldComponentUpdate() controls if the component should be recalculated or not. You should use it, when you are rendering statical data, for example. The output of the component will not change, so you could just return false and the first version of the component will be used for ever ;)

Upvotes: 0

KRONWALLED
KRONWALLED

Reputation: 1442

You're changing a so called Virtual DOM node. For every change in a virtual node shouldComponentUpdate() gets called. If you don't implement it yourself it will always return true;

So if you only want to reload your CookingClass in specific cases you would have to implement it yourself.

The pro of React is that it will only re-render Native DOM nodes when they will get changed in the Virtual DOM. This is the "render" which makes React so fast.

Upvotes: 3

Related Questions