Pure components and React.memo are essential tools in React.js for optimizing performance by preventing unnecessary re-renders. This chapter will cover the concepts from basic to advanced, providing detailed explanations and examples to ensure a comprehensive understanding.
A Pure Component in React is a component that performs a shallow comparison of its props and state to determine whether the component should re-render. If the props and state have not changed, the component does not re-render, which can improve performance.
import React, { PureComponent } from 'react';
class MyComponent extends PureComponent {
render() {
console.log('MyComponent render');
return {this.props.value};
}
}
export default MyComponent;
In this example, MyComponent
will only re-render if its props.value
changes.
React.memo
is a higher-order component that memoizes a functional component. It behaves similarly to PureComponent
but is used with functional components.
import React from 'react';
const MyComponent = React.memo(({ value }) => {
console.log('MyComponent render');
return {value};
});
export default MyComponent;
In this example, MyComponent
will only re-render if its props.value
changes.
Using Pure Component and React.memo
can significantly improve the performance of a React application by reducing unnecessary re-renders. This is particularly useful in large applications with complex component trees.
Pure Component performs a shallow comparison of the current and previous props and state. If all props and state are equal (shallow comparison), the component does not re-render.
import React, { PureComponent } from 'react';
class MyComponent extends PureComponent {
render() {
console.log('MyComponent render');
return {this.props.value};
}
}
class App extends React.Component {
state = {
value: 0
};
increment = () => {
this.setState({ value: this.state.value + 1 });
};
render() {
return (
);
}
}
export default App;
value
in the state is incremented.MyComponent
only re-renders if this.state.value
changes, as it performs a shallow comparison of props.React.memo
works by memoizing the functional component. It performs a shallow comparison of the current and previous props. If all props are equal (shallow comparison), the component does not re-render.
import React, { useState } from 'react';
const MyComponent = React.memo(({ value }) => {
console.log('MyComponent render');
return {value};
});
function App() {
const [value, setValue] = useState(0);
const increment = () => {
setValue(value + 1);
};
return (
);
}
export default App;
value
in the state is incremented.MyComponent
only re-renders if value
changes, as it performs a shallow comparison of props.React.memo
is used with functional components.class MyComponent extends PureComponent { ... }
React.memo
: const MyComponent = React.memo(function MyComponent(props) { ... })
import React, { PureComponent } from 'react';
class PureChild extends PureComponent {
render() {
console.log('PureChild render');
return Pure Component: {this.props.value};
}
}
class App extends React.Component {
state = {
value: 0
};
increment = () => {
this.setState({ value: this.state.value + 1 });
};
render() {
return (
);
}
}
export default App;
PureChild render
is logged only when the value
prop changes.PureChild
.
import React, { useState } from 'react';
const MemoChild = React.memo(({ value }) => {
console.log('MemoChild render');
return Memo Component: {value};
});
function App() {
const [value, setValue] = useState(0);
const increment = () => {
setValue(value + 1);
};
return (
);
}
export default App;
Output:
MemoChild render
is logged only when the value
prop changes.MemoChild
.React.memo
By default, React.memo
performs a shallow comparison of props. You can provide a custom comparison function to control the behavior.
import React, { useState } from 'react';
const MemoChild = React.memo(
({ value }) => {
console.log('MemoChild render');
return Memo Component: {value};
},
(prevProps, nextProps) => {
// Custom comparison: only re-render if value is an even number
return prevProps.value % 2 === nextProps.value % 2;
}
);
function App() {
const [value, setValue] = useState(0);
const increment = () => {
setValue(value + 1);
};
return (
);
}
export default App;
MemoChild
re-renders only if value
changes from even to odd or vice versa.While Pure Component and React.memo
can improve performance, they can also introduce overhead due to shallow comparisons. Use them judiciously, especially in large component trees or when dealing with deeply nested objects.
React.memo
for complex comparison logic, but be cautious of the performance implications.React.memo
for functional components.React.memo
provide fine-grained control over re-renders.In this example, we’ll create a simple app that displays a list of users and a counter. The user list component will be a Pure Component to prevent unnecessary re-renders when the counter updates.
import React, { PureComponent, Component } from 'react';
// PureComponent to display a list of users
class UserList extends PureComponent {
render() {
console.log('UserList render');
const { users } = this.props;
return (
User List
{users.map(user => (
- {user.name}
))}
);
}
}
class App extends Component {
state = {
users: [
{ id: 1, name: 'John Doe' },
{ id: 2, name: 'Jane Smith' },
{ id: 3, name: 'Jack Johnson' }
],
counter: 0
};
incrementCounter = () => {
this.setState({ counter: this.state.counter + 1 });
};
render() {
return (
Counter: {this.state.counter}
);
}
}
export default App;
users
prop changes.UserList
component does not re-render because the users
prop has not changed.In this example, we’ll create a simple app that displays a list of products and a search bar. The product list component will use React.memo
to prevent unnecessary re-renders when the search query updates.
import React, { useState, memo } from 'react';
// Memoized functional component to display a list of products
const ProductList = memo(({ products }) => {
console.log('ProductList render');
return (
Product List
{products.map(product => (
- {product.name}
))}
);
});
function App() {
const [products] = useState([
{ id: 1, name: 'Laptop' },
{ id: 2, name: 'Smartphone' },
{ id: 3, name: 'Tablet' }
]);
const [search, setSearch] = useState('');
const handleSearchChange = (e) => {
setSearch(e.target.value);
};
return (
);
}
export default App;
products
prop changes.ProductList
component does not re-render because the products
prop has not changed.Pure Component and React.memo are powerful tools in React.js that help optimize performance by preventing unnecessary re-renders. By understanding how they work and applying best practices, you can build more efficient and responsive React applications.Happy coding !❤️