Dev

By Carlos Santana on
Reading time: 3 minutes

React-SPWrc.png

A lot of people get confused by the difference between a functional component (or stateless component) and a Pure component. Most of them think they are the same, but that is wrong. When we use a Pure Component, we need to import PureComponent from React like this:

import React, { PureComponent } from 'react';

If your React component's render method is "pure" (meaning it renders the same result, given the same props and state), you can use this function to improve the performance of your application. A Pure Component performs a shallow comparison for the props and nextProps objects as well as the state and nextState objects. Pure components do not have the shouldComponentUpdate method, and if we try to add it, we will get a warning from React:

PureComponentWarning-BbIeH.png

In this post, we are going to create a basic example to understand how Pure Components works.

Creating React Pure Components

Before we start creating the Pure components we need to install the React Developer Tools to do a debug in our application. You can download the RDT from here.

Basically, we will create a component where we will sum all numbers entered in an input. First, let's modify our App.js file to include our Numbers component (you can replace your Home component for this one).

import React, { Component } from 'react';

// We import our Numbers component here...
import Numbers from './Numbers/Numbers';
import logo from '../shared/images/logo.svg';
import './App.css';

class App extends Component {
  render() {
    return (
      <div className="App">
        <header className="App-header">
          <img src={logo} className="App-logo" alt="logo" />

          <Numbers />
        </header>
      </div>
    );
  }
}

export default App;
File: src/components/App.js

Then we need to create our Numbers component:

// Dependencies
import React, { Component } from 'react';

// Components
import Result from './Result';

// Styles
import './Numbers.css';

class Numbers extends Component {
  state = {
    numbers: '', // Here we will save the input value
    results: [] // In this state we will save the results of the sums
  };

  handleNumberChange = e => {
    const { target: { value } } = e;

    // Converting the string value to array 
    // "12345" => ["1", "2", "3", "4", "5"]
    const numbers = Array.from(value);

    // Summing all numbers from the array
    // ["1", "2", "3", "4", "5"] => 15
    const result = numbers.reduce((a, b) => Number(a) + Number(b), 0);

    // Updating the local state
    this.setState({
      numbers: value,
      results: [...this.state.results, result]
    });
  }

  render() {
    return (
      <div className="Numbers">
        <input
          type="number"
          value={this.state.numbers}
          onChange={this.handleNumberChange}
          placeholder="Write numbers here..."
        />

        {/* Rendering the results array */}
        <ul>
          {this.state.results.map((result, i) => (
            <Result key={i} result={result} /> ))}
        </ul>
      </div>
    );
  }
}

export default Numbers;
File: src/components/Numbers/Numbers.js

Then, let's create the Result component (as a Class Component): 

import React, { Component } from 'react';

class Result extends Component {
  render() {
    return <li>{this.props.result}</li>;
  }
}

export default Result;
File: src/components/Numbers/Result.js

We can add some basic styles as well:

.Numbers {
  padding: 30px;
}

.Numbers input[type=number]::-webkit-inner-spin-button,
.Numbers input[type=number]::-webkit-outer-spin-button {
  -webkit-appearance: none;
  margin: 0;
}

.Numbers input {
  width: 500px;
  height: 60px;
  font-size: 20px;
  outline: none;
  border: 1px solid #ccc;
  padding: 10px;
}

.Numbers ul {
  margin: 0 auto;
  padding: 0;
  list-style: none;
  width: 522px;
}

.Numbers ul li {
  border-top: 1px solid #ccc;
  border-left: 1px solid #ccc;
  border-right: 1px solid #ccc;
  padding: 10px;
}

.Numbers ul li:first-child {
  border-top: none;
}

.Numbers ul li:last-child {
  border-bottom: 1px solid #ccc;
}
File: src/components/Numbers/Numbers.css

If you run the application you will see something like this:

NumbersComponent-MUB5u.png

We are using an input to type numbers, which means we will only accept numbers, if you start writing numbers (1, then 2, then 3, etc.), you will see the results of the sum on each row (0 + 1 = 1, 1 + 2 = 3, 3 + 3 = 6). 

Numbers-mizAo.png

Maybe this looks very simple to you, but let's inspect the application using React Developer Tools, we need to enable the Highlight Updates option.

ReactDevTools-nGg3B.png

After this, start writing multiple numbers in the input (quickly), and you will see all the renders that React is performing.

As you can see, React is doing a lot of renderings. When the highlights are red, it means the performance of that component is bad. Here's when Pure Components will help us; let's migrate our Result component to be a Pure Component:

import React, { PureComponent } from 'react';

class Result extends PureComponent {
  render() {
    return <li>{this.props.result}</li>;
  }
}

export default Result;
File: src/components/Numbers/Result.js

Now if we try to do the same with the numbers, let's see the difference.

renders-pure.gif

As you can see, with the Pure Component React, do less renders in comparison to a Class Component. Probably now you think that if we use a Stateless component instead of a Pure Component, the result will be the same. Unfortunately, this won't happen; if you want to verify this, let's change the Result component again and convert it into a Functional Component:

Only members can see all the codes
You can Login or Sign Up

File: src/components/Numbers/Result.js

Even the code is less, but let's see what happen with the renders.

renders-stateless.gif

As you can see, the result is the same as the Class Component, which means not all the time using a Stateless component necessary will help us improve the performance of our application. If you have components that you consider are pure, consider converting them into Pure components.

I hope you liked this post if you want to help us to continue writing more React posts please do not forget to follow us in our Social media accounts: Twitter, Facebook, and Youtube.

avatarLeave a comment

Your comment

Only members can comment. You can Login or Sign Up