techStackGuru

React Pure Components


These React components optimize performance by implementing a shallow comparison of props and states to decide whether the component should be rerendered.

React re-renders components when they change props or state, and updates their DOM accordingly. However, in some cases, it might not be necessary to actually re-render a component if the state or props are the same. In this scenario, React Pure Components are useful.

A React Pure Component extends the React.PureComponent class rather than the regular ReactComponent class. As a result, they inherit React.PureComponent's shallow comparison behavior. In shallow comparison, React compares the props and state of the component each individually, rather than performing a deep comparison across all properties and states.

React Pure Components automatically perform shallow comparisons when new props or states are received. The re-rendering process for a component will be skipped if the new values are equal to the previous ones, improving application performance. It is especially useful when dealing with large or complex components with expensive rendering operations.

There are some scenarios for which React Pure Components are not suitable. Since shallow comparison relies on object references to determine equality, they are most effective when a component's props and state are immutable (i.e., their values are not changed by mutation). React might fail to re-render when the props or state values are changed by mutating them.

Example of a React Pure Component

import React from 'react';

class MyPureComponent extends React.PureComponent {
  render() {
    return (
      <div>
        <h1>Hello, {this.props.name}!</h1>
        <p>Age: {this.props.age}</p>
      </div>
    );
  }
} 

React.PureComponent is derived from React.Component instead of the regular React.Component class in this example. It displays a greeting message and the person's age using a simple rendering method.

The following is an example of how myPureComponent could be used in a parent component

import React from 'react';
import MyPureComponent from './MyPureComponent';

class ParentComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      name: 'John',
      age: 25,
    };
  }

  componentDidMount() {
    setTimeout(() => {
      this.setState({ age: 26 });
    }, 2000);
  }

  render() {
    return (
      <div>
        <h2>Parent Component</h2>
        <MyPureComponent name={this.state.name} age={this.state.age} />
      </div>
    );
  }
} 

ParentComponent renders a MyPureComponent instance and passes its name and age properties. In this case, the name prop stays the same, but the age prop is updated after 2 seconds using setState.

React carries out a shallow comparison of MyPureComponent's props since it extends React.PureComponent. If the age prop is updated, React detects the difference between the old and new values and re-renders MyPureComponent based on the new value. When the name prop changes, React will also re-render the page.

With React.PureComponent, you can avoid unnecessary re-renders by handling shallow comparison for you automatically.

Another example without re-render

import React from 'react';

class User extends React.PureComponent {
  render() {
    const { name, age } = this.props;
    return (
      <div>
        <p>Name: {name}</p>
        <p>Age: {age}</p>
      </div>
    );
  }
} 

Example with re-render

import React, { Component } from 'react';
import User from './User';

class App extends Component {
  state = {
    users: [
      { name: 'John', age: 30 },
      { name: 'Jane', age: 25 },
      { name: 'Mike', age: 40 },
    ],
  };

  componentDidMount() {
    // Simulate changing the age of the first user after 2 seconds
    setTimeout(() => {
      this.setState({
        users: [
          { name: 'John', age: 31 }, // Age changed from 30 to 31
          { name: 'Jane', age: 25 },
          { name: 'Mike', age: 40 },
        ],
      });
    }, 2000);
  }

  render() {
    return (
      <div>
        {this.state.users.map((user, index) => (
          <User key={index} name={user.name} age={user.age} />
        ))}
      </div>
    );
  }
}

export default App