#component, #JavaScript, #pure, #React
16 March 2019
Bartłomiej Rgacewicz
Article mage

PureComponent in React – Do not forget about it!

Building React app is all about creating components and wiring them together. We can have a stateful or stateless component. React API gives us a couple of ways how we can declare them. There is a functional component, Class Component, and PureComponent. Today I want to share my experience and knowledge about working with PureComponent because I think that developers usually forgot about it.

The basic concept behind react is to re-render our components basing on changes of state or properties that are passed to those components.

When building a React app we have to keep in mind that each render cost some amount of memory. Probably this won’t be the case when you have a few components in your app. However when you have hundreds of components it may influence the efficiency of the app. Especially when plenty of components request rerenders really frequently or your device has the limited amount of memory.

Check out our article on how to build Xbox app using React. Xbox allows using only 25% of memory for apps.

Here comes PureComponent which gives us an opportunity to optimize numbers of renders of our components. In this article, I will show you how PureComponent is working under the hood. How to use it and what you should avoid when using PureComponent.

Difference between Component and PureComponent

Declaring PureComponent looks the same as declaring standard Class Component but instead of extending React.Component we have to extend React.PureComponent.

 

import React from 'react'

// Standard Class Component
class MyComponent extends React.Component {
  render () {
    return (
      <div>MyComponent</div>
    )
  }
}

// PureComponent
class MyPureComponent extends React.PureComponent {
  render () {
    return (
      <div>MyPureComponent</div>
    )
  }
}

The first question which may occur is – what’s the difference and why PureComponent is better?
Whole “magic” is behind how checkShouldComponentUpdate is implemented for these classes. The code for this function is here.

Every time Class Component gets new props, state or context it’s always rerendered. You can think that Class Component always return true from shouldComponentUpdate.

In PureComponent react is making shallow comparision of current component props and state with new props and state. If those are the same component isn’t rerendered but if they differ react rerenders component.

How PureComponent is working

After theoretical knowledge, we can write some code.

In this example, we have two rockets in our main RocketStation component render method.

<Rocket altitude={this.state.altitude} />
<PureRocket altitude={this.state.altitude} />

One as example of Class Component and the other one for PureComponent.

Also, we have two buttons:
“Fly!” – on every click increments our main component altitude state since it became 100.
“Touch down!” – changes altitude to 0 and brings our rockets back to the ground.

So let’s test our app and see how it works.

console logs

As you can see in the console above Class Component rerenders on every props update, no matter if they differ or not. On the other hand, PureComponent stopped logs after attitude reaches 100. The same situation is for rocket colour which is randomly generated on each component render. When PureComponent reaches 100 Rocket colour stops changing.

That’s because react checks (shallow comparison) for PureComponent if the new props or state is different than the previous one. If it’s not then PureComponent isn’t updated. But when we reset rocket altitude using Touch down! it’s rerendering again.

In this simple example, we easily decreased the amount of our app component’s rerenders with PureComponent usage.

Obviously, usually, the case won’t be that easy and maybe you will want to update your component only when a specific value of props or state is changed and you don’t care about changes of other ones. If so please remember about shouldComponentUpdate lifecycle method which you can implement inside your Class Component to decide whether react should rerender this component or not.

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

Avoid binding functions and values when using PureComponent

PureComponent without any doubt is a convenient and easy way to optimize your react app. But you have to keep in mind how it’s working under the hood and what you should avoid because of that shallow comparison I’ve mentioned before. I will show you two most important rules that you have to remember when rendering PureComponent

Avoid binding functions in the renderer

render() {
 return (
   <PureRocket onStart={() => {
       console.log('rocket starts')
   }}/>
 )
}

Binding function in renderer with PureComponent cause update this component on every parent component render anyway. That’s because on every render a new function instance is created. So let’s declare this function in our parent ClassComponent and avoid this.

onPureRocketStart = () => console.log('rocket starts')

render() {
 return (
   <PureRocker
     onStart={this.onPureRocketStart}
   />
 )
}

I strongly recommend you to use this technique even if you aren’t using pure component because of render bindings costs.

Avoid declaring values inside the renderer

render() {
 const fuel = 100
 return <PureRocket rocketFuel={fuel} />
}

Exact the same situation as with binding function in the render. Rendering variables in render() function causes rerender of PureComponent even if the number of fuels won’t change.

To avoid this you can always pass value from components’ state

state = {
  fuel: 100
}

render() {
  return <PureRocket rocketFuel={this.state.fuel} />
}

When it is a constant value and you don’t need to change it you can simply declare it as the Class property

fuel = 100

render() {
  return <PureRocket rocketFuel={this.fuel} />
}

With this approach reference to fuel, variable won’t change so shallow comparison will check only if the value has changed.

React.memo

You can use PureComponent by extending it to your javascript Class based component but you may want to get the same benefits of shallow comparison with function component. Since React v16.6.0 you can use React.memo to wrap your function component. You can read more about it in our article about the newest features in React v16.6 and v.16.7.

Summary

I hope that with this article I’ve encouraged you to write more optimized React’s apps with fewer unnecessary rerenders. It’s great that you don’t really need to spend hours to achieve that. But please keep in mind that there are some pitfalls which can come across if you will be distracted.

Picked for you

View our blog page
Interested? - let us know ☕
[email protected] Get Estimation