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.
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.
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.
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>
);
}
}
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