Understand PureComponent from React source code.

Deep Insight Into PureComponent and shallowEqual From React Source Code

PureComponent was added into React from 15.3. Just as we can see from the official site introduction:

React.PureComponent is similar to React.Component. The difference between them is that React.Component doesn’t implement shouldComponentUpdate(), but React.PureComponent implements it with a shallow prop and state comparison.If your React component’s render() function renders the same result given the same props and state, you can use React.PureComponent for a performance boost in some cases.

The interesting things are:

1. How is it implemented?

2. What does it mean “a shallow prop and state comparison”?

1. PureComponent Definition & Implementation

To answer this question, let’s first have a look at the definition of PureComponent.

PureComponent comes from ComponentDummy. No problems at all. But our questions is: where is the function shouldComponentUpdate()? It was expected to implement something like

shouldComponentUpdate() {
return !shallowEqual( ... );
}

But where are they?

Actually it could be found from ReacFiberClassComponent.js. The history of this file looks quite complicated, and it might not be stable yet at this moment since you could find bunches of xxx.new.js & xxx.old.js in the folder packages/react-reconciler/src/. It doesn’t matter. Let’s just check one of the released version like 16.3-dev

Found it!

Here it shallowly compares old/new props, and old/new states.

And it’s easy to understand the differences bewteen PureComponent and Function Component

1. PureComponent has its ow states, but Function Component, also known as Stateless Component, doesn’t.

2. As a result, PureComponent would prevent unnecessary rendering, while Function Component would perform rendering all the time even if the old props and new props are same.

Therefore, PureComponent could provide better performances.

2. What Does it Mean “a shallow prop and state comparison”?

The function shallowEequal locates in the shared library, and it exists for a quite long time.

Before checking the source code, let’s just take some time to understand Object.is().

Object.is() determines if two values are same or not. Here it says ‘two values’, which implicits at least 2 things:

  • it compares the basic 6 data types very well;
  • it cannot compare objects properly. This is very important to us.

To understand Object.is() better, please check the official document. It’s also strongly recommended to read the examples.

Back to shallowEqual(), here’s the source code:

Firstly, it check the values with Object.is(). If they are different, there are two possibilities:

  1. One of them is an object:

In this case, it simply returns false since one is an object but another one is not.

  if (
typeof objA !== 'object' || === null ||
typeof objB !== 'object' || === null {
return false;
}

2. Both of them are objects:

In this case, it checks in 2 steps:

Step #1. check the length of them. Apparently, the 2 objects are not same if their lengths are different;

  if (keysA.length !== keysB.length) {
return false;
}

Step #2. chech value of each member with Object.is() in a loop.

Okay, as we can see, it’s just checking VALUES of each member. What would happen?

As long as one of the members is an object, the comparison may return unexpected result to us.

Take an instance. Guess the result of the code below. Will it return true of false?

var foo = { a: "a" };
var bar = { a: "a" };
Object.is(foo, bar);

The answer is false.

Saying, even if the new props are exactly same as the old one, the PureComponent still performes the re-render. I don’t think it’s the result as we expects.

3. How To Use PureComponent Properly?

Let’s have an experiment to build an app with 2 PureComponents.

  • PureSample: with props of { id, name }
  • FakePure: with props of { user }, where user contains two members { id, name}

Now, let’s build a container component to update them with the same props:

You could play with it here:

As clicking the button, console will only show one log:

Fake Sample rendering ...

Saying, PureSample did not re-render as expected, whileFakePureSample rendered with the same props.

4. Summary

From all the analysis and tests above, it’s easy to answer the question now. As we are using PureComponent, we have to make sure every member of the props and states are all in base data types, and don’t use any objects.

Hope it helps.

--

--

--

Full Stack Developer (.NET | Angular)

Love podcasts or audiobooks? Learn on the go with our new app.

Recommended from Medium

Implementing Screen Transitions on You.i Engine One With React Navigation

Building a Web VR application using A-Frame (part 1): Hello world

Console.log tricks : How to style a log

Clean Architecture for SwiftUI

How Redux Actions / Reducers Work

Buy a Good QualityMattress! https://t.co/JxTSPGKaUd

How to write a ‘Good’ unit test in Angular

Adventures in the Virtual DOM — Part 1: Defining the Problem

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Derek Ji

Derek Ji

Full Stack Developer (.NET | Angular)

More from Medium

Creating Ext JS applications with coon.js — Part 3: Configuration Details and defining Plugins

Handle Multiple Promises using Async/Await

How do I run an AdonisJS seeder in Staging and Production?

Heroku Run Console Menu Button Screenshot

ExpressWebJs Maintenance mode