shouldComponentUpdate

For many developers, the way the reconciler algorithm works is confusing. They often think that since React is smart enough to find out the shortest path to apply the changes to the DOM, the render methods of the components that are not changed do not ever get called. That's unfortunately far from being true.

In fact, to find out the necessary steps to reduce the DOM operations, React has to fire the render methods of all the components and compare the results with the previous ones.

If nothing changes, no changes will be made in the DOM, which is great. But if our render methods do complex operations, React will take some time to figure out that no operations have to be done, which is not optimal.

We surely want our components to be simple, and we should avoid doing expensive operations inside the renderer. However, sometimes we simply cannot manage this and our applications become slow, even if the DOM is not touched at all.

React is not able to figure out which components do not need to be updated, but we have a function that we can implement to tell the library whether to update a component or not.

The method is called shouldComponentUpdateand if it returns false, the component and all its children's render methods are not called during an update of its parents.

Let's create a List component to understand this method:

  class List extends Component

The List component has a constructor where we initialize the list and we bind the event handler:

  constructor(props) { 
super(props);

this.state = {
items: ['foo', 'bar']
};

this.handleClick = this.handleClick.bind(this);
}

We then define the event handler that appends a new item to the list and stores the resulting array into the state:

  handleClick() { 
const items = this.state.items.slice();
items.unshift('baz');

this.setState({
items
});
}

Finally, we specify the render method where we loop through the items displaying every single element of the list and declaring button with its onClick event handler:

  render() { 
return (
<div>
<ul>
{this.state.items.map(item => <li key={item}>{item}</li>)}
</ul>

<button onClick={this.handleClick}>+</button>
</div>
);
}

Now, try to add the following code to the previously created list:

  shouldComponentUpdate() { 
return false;
}

You can see that clicking on the + button has no effect whatsoever on the application inside the browser, even though the state changes. That is because we are telling React that the component does not need to be updated.

Returning false all the time is far from useful, and so developers usually check if the props or the state are changed inside that method.

In the case of List, for example, we should check if the items array has been modified or not, and return a value accordingly.

The shouldComponentUpdate method passes two parameters that we can use to implement those checks, the first parameter represents nextProps while the second parameter represents  nextState.

In our case, we could do something like this:

  shouldComponentUpdate(nextProps, nextState) { 
return this.state.items !== nextState.items;
}

We return true only if the items are changed, while we stop the rendering in any other case. Suppose, for example, that List is a child of a component that gets updated frequently but its state does not affect the List in any way: We can use shoudlComponentUpdate to tell React to stop running the render methods from that component to its children.

Checking if all the props and all the state attributes are changed is a boring job, and it is sometimes hard to maintain the complex shouldComponentUpdate implementations, especially when the requirements change frequently.

For that reason, React gives us a special component from which we can inherit and which implements a shallow comparison of all the props and the state attributes for us.

Using it is pretty straightforward; we just have to extend React.PureComponent instead of React.Component when we create our component classes.

It is important to notice that the shallow comparison, as the name suggests, does not check for deep and nested properties in objects, and it can sometimes give unexpected results.

It works very well with immutable data structures, which we will see in more detail later in this chapter. It is worth saying that performing a deep comparison of complex objects can sometimes be more expensive than the render method itself.

That is why PureComponent should be used only when it is needed and only once the performance has been measured and you have figured out which components are taking too much time to be executed.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.144.104.29