When I build sales dashboards, support portals, or admin screens, I often start with a simple activity list. It might show recent orders, new tickets, or customer updates. The feature works well at first, but then parent components update for unrelated reasons and every row in the list renders again.
That is where Pure Components help. They let React skip a render when a component receives the same data as before, which keeps larger frontend tools responsive.
This guide shows what Pure Components are, how shallow comparison works, and how to use the modern functional-component approach with React.memo.
What Are Pure Components in React?
A component is a reusable part of a React interface. For example, a SalesActivityRow component can display one activity inside a sales dashboard.
A Pure Component is a component that avoids rendering again when its props and state have not changed. Props are values a parent component sends to a child component. State is data that a component remembers between renders.
React normally runs a component again when its parent renders. That behavior keeps the UI accurate, but it can also create unnecessary work in a dashboard with many rows, charts, filters, or tables.
In class-based React code, you can use React.PureComponent. In modern React applications, developers usually create functional components and wrap them with React.memo.
A Pure Component uses a shallow comparison. React compares top-level values only:
- Primitive values such as strings, numbers, and booleans compare by value.
- Objects, arrays, and functions compare by reference.
- A new array or object counts as changed, even if its contents look identical.
For a useful foundation, review how to set up your first React application and understand React component structure.
Why Pure Components Matter in React
A render means React calls your component function and checks whether the browser DOM needs changes. React does not always update the real DOM after every render, but large component trees still take time to calculate.
Consider a sales activity dashboard:
- A manager clicks a button to update a page title.
- The dashboard component renders again.
- Every activity row also renders, even though no activity changed.
- A list of 500 rows can now do unnecessary work.
A Pure Component helps React avoid rendering those unchanged rows.
This matters most in:
- Dashboards with charts, tables, and long lists
- Client-side data views with filtering and sorting
- API-driven interfaces that refresh frequently
- Admin portals with reusable table rows
- Local frontend applications that manage large state arrays
Pure Components do not replace good application design. They work best after you keep your state focused and pass stable props to child components.
Pro Tip: I have found that
React.memoonly helps when props stay stable. If you create a new object, array, or inline function during every parent render, React sees a changed reference and renders the child anyway.
Pure Components in React With Classes
React.PureComponent is the class-based version of a Pure Component. It automatically performs a shallow comparison of props and state.
Here is a complete sales activity dashboard example.
import React, { PureComponent, Component } from "react";
class ActivityRow extends PureComponent {
render() {
const { activity } = this.props;
console.log(`Rendering activity: ${activity.customer}`);
return (
<li>
<strong>{activity.customer}</strong> - {activity.message}
</li>
);
}
}
class SalesDashboard extends Component {
state = {
title: "Today’s Sales Activity",
activities: [
{ id: 1, customer: "Olivia Carter", message: "Requested a product demo" },
{ id: 2, customer: "Ethan Brooks", message: "Opened a pricing proposal" },
{ id: 3, customer: "Mia Thompson", message: "Scheduled a follow-up call" }
]
};
updateTitle = () => {
this.setState({
title: "Sales Activity Dashboard"
});
};
render() {
const { title, activities } = this.state;
return (
<main>
<h1>{title}</h1>
<button onClick={this.updateTitle}>
Update Dashboard Title
</button>
<ul>
{activities.map((activity) => (
<ActivityRow key={activity.id} activity={activity} />
))}
</ul>
</main>
);
}
}
export default SalesDashboard;Sample output
Today’s Sales Activity
[Update Dashboard Title]
Olivia Carter - Requested a product demo
Ethan Brooks - Opened a pricing proposal
Mia Thompson - Scheduled a follow-up call
You can refer to the screenshot below to see the output.

When you click the button, SalesDashboard renders because its title changes. However, each ActivityRow receives the same activity object reference. Since ActivityRow extends PureComponent, React skips rendering those rows.
The key property gives React a stable identity for each list item. Learn more about using component values through props in React and common React component key prop practices.
Modern Pure Components With React.memo
Modern React uses functional components. A functional component is a JavaScript function that returns JSX, which is the HTML-like syntax React uses to describe interface elements.
React.memo gives a functional component Pure Component behavior. React renders the memoized component again only when its props change.
Here is the same dashboard built with modern React patterns.
import React, { useState, memo } from "react";
const ActivityRow = memo(function ActivityRow({ activity }) {
console.log(`Rendering activity: ${activity.customer}`);
return (
<li>
<strong>{activity.customer}</strong> - {activity.message}
</li>
);
});
export default function SalesDashboard() {
const [title, setTitle] = useState("Today’s Sales Activity");
const activities = [
{ id: 1, customer: "Olivia Carter", message: "Requested a product demo" },
{ id: 2, customer: "Ethan Brooks", message: "Opened a pricing proposal" },
{ id: 3, customer: "Mia Thompson", message: "Scheduled a follow-up call" }
];
function updateTitle() {
setTitle("Sales Activity Dashboard");
}
return (
<main>
<h1>{title}</h1>
<button onClick={updateTitle}>
Update Dashboard Title
</button>
<ul>
{activities.map((activity) => (
<ActivityRow key={activity.id} activity={activity} />
))}
</ul>
</main>
);
}Sample output
Today’s Sales Activity
[Update Dashboard Title]
Olivia Carter - Requested a product demo
Ethan Brooks - Opened a pricing proposal
Mia Thompson - Scheduled a follow-up call
You can refer to the screenshot below to see the output.

The useState hook adds state to a functional component. A hook is a React function that lets a component use React features such as state and effects.
This example demonstrates the concept, but it has one performance issue. The activities array is created again whenever SalesDashboard renders. That means each activity object is also new, so React.memo cannot skip child renders.
Move static data outside the component, or use useMemo when the list comes from calculated data.
Keep Props Stable With useMemo
useMemo stores the result of a calculation between renders. Use it when a computed array should keep the same reference unless its dependencies change.
The following dashboard lets a manager toggle the display order. It uses useMemo to calculate the displayed activities and keeps the child row component memoized.
import React, { memo, useMemo, useState } from "react";
const initialActivities = [
{ id: 101, customer: "Olivia Carter", message: "Requested a product demo" },
{ id: 102, customer: "Ethan Brooks", message: "Opened a pricing proposal" },
{ id: 103, customer: "Mia Thompson", message: "Scheduled a follow-up call" }
];
const ActivityRow = memo(function ActivityRow({ activity }) {
console.log(`Rendering activity: ${activity.customer}`);
return (
<li>
<strong>{activity.customer}</strong> - {activity.message}
</li>
);
});
export default function SalesDashboard() {
const [showNewestFirst, setShowNewestFirst] = useState(true);
const [dashboardTitle, setDashboardTitle] = useState(
"Sales Activity Dashboard"
);
const displayedActivities = useMemo(() => {
if (showNewestFirst) {
return [...initialActivities].reverse();
}
return initialActivities;
}, [showNewestFirst]);
function toggleActivityOrder() {
setShowNewestFirst((currentValue) => !currentValue);
}
function renameDashboard() {
setDashboardTitle("Daily Sales Overview");
}
return (
<main>
<h1>{dashboardTitle}</h1>
<button onClick={toggleActivityOrder}>
{showNewestFirst ? "Show Oldest First" : "Show Newest First"}
</button>
<button onClick={renameDashboard}>
Rename Dashboard
</button>
<ul>
{displayedActivities.map((activity) => (
<ActivityRow key={activity.id} activity={activity} />
))}
</ul>
</main>
);
}Sample output
Sales Activity Dashboard
[Show Oldest First] [Rename Dashboard]
Mia Thompson - Scheduled a follow-up call
Ethan Brooks - Opened a pricing proposal
Olivia Carter - Requested a product demo
You can refer to the screenshot below to see the output.

The displayedActivities value changes only when showNewestFirst changes. Clicking Rename Dashboard updates the title but does not rebuild the activity array. That gives React.memo a real opportunity to skip unnecessary row renders.
The expression [...initialActivities].reverse() creates a copy before calling the JavaScript reverse() method. The copy protects the original array from array mutation, which means changing an existing array directly.
Pure Components and React State Arrays
A React state array stores a list inside component state. Common examples include shopping-cart items, support tickets, notifications, and records returned by an API.
React expects an immutable update. An immutable update creates a new array or object instead of changing the existing one. This makes state changes predictable and lets React compare old and new references correctly.
Do not reverse a state array directly.
activities.reverse();
setActivities(activities);
This code changes the existing array in place. React may not recognize the update correctly, and other parts of your UI may now see an unexpected order.
Instead, create a copied array first.
setActivities((currentActivities) => [
...currentActivities
].reverse());
Here is a complete example with the useState hook and an event handler. An event handler is a function React runs after an action such as a button click.
import React, { useState } from "react";
export default function SupportTicketList() {
const [tickets, setTickets] = useState([
{ id: "T-1001", customer: "Noah Williams", subject: "Cannot update billing address" },
{ id: "T-1002", customer: "Ava Martinez", subject: "Need invoice copy" },
{ id: "T-1003", customer: "Liam Johnson", subject: "Account access issue" }
]);
function reverseTickets() {
setTickets((currentTickets) => [...currentTickets].reverse());
}
return (
<main>
<h1>Customer Support Tickets</h1>
<button onClick={reverseTickets}>
Reverse Ticket Order
</button>
<ul>
{tickets.map((ticket) => (
<li key={ticket.id}>
<strong>{ticket.id}</strong>: {ticket.customer} - {ticket.subject}
</li>
))}
</ul>
</main>
);
}Sample output
Customer Support Tickets
[Reverse Ticket Order]
T-1001: Noah Williams - Cannot update billing address
T-1002: Ava Martinez - Need invoice copy
T-1003: Liam Johnson - Account access issue
After clicking Reverse Ticket Order, the screen displays:
T-1003: Liam Johnson - Account access issue
T-1002: Ava Martinez - Need invoice copy
T-1001: Noah Williams - Cannot update billing address
React receives a new array reference, updates the state, and renders the ticket list in the new order. This pattern works well when users need to change the visible order permanently.
For related click logic, see this guide on handling events in React.
Pro Tip: I have seen direct
reverse()calls cause bugs in filters, pagination, and export features because several parts of the app shared the same array. I always copy first, even when the example looks small.
Use toReversed() for a Cleaner Immutable Update
Modern JavaScript includes toReversed(). Unlike reverse(), it returns a new reversed array and leaves the original array unchanged.
That makes it a clean option for React state and derived display data.
import React, { useState } from "react";
export default function RecentOrders() {
const [orders] = useState([
{ id: "ORD-501", customer: "Emma Davis", total: 245 },
{ id: "ORD-502", customer: "James Wilson", total: 180 },
{ id: "ORD-503", customer: "Sophia Moore", total: 320 }
]);
const newestOrders = orders.toReversed();
return (
<main>
<h1>Recent Orders</h1>
<ul>
{newestOrders.map((order) => (
<li key={order.id}>
<strong>{order.id}</strong> - {order.customer} - ${order.total}
</li>
))}
</ul>
</main>
);
}Sample output
Recent Orders
ORD-503 - Sophia Moore - $320
ORD-502 - James Wilson - $180
ORD-501 - Emma Davis - $245
This approach works well when you only need a reversed view. You do not need to store both the original and reversed lists in state.
Check browser and build-tool support before you standardize on toReversed() in an older project. If support is uncertain, [...orders].reverse() remains a clear and reliable alternative.
When Not to Use a Pure Component
Do not wrap every React component with React.memo. Memoization adds its own comparison step, and that work can exceed the cost of rendering a tiny component.
Use React.memo when:
- A component renders often with unchanged props.
- A component displays many rows or expensive calculations.
- A parent updates frequently for unrelated reasons.
- You have measured or observed a render performance problem.
Skip it when:
- The component is very small.
- Its props change every render.
- You do not have a noticeable performance issue.
- Memoization makes the code harder to understand.
Start with a clean component design. Then add memoization where it solves a real rendering problem. You can also explore practical React component optimization techniques when a dashboard grows larger.
Things to Keep in Mind
- Avoid direct state mutation: Never call
reverse()directly on a React state array because it changes the existing array. - Copy before reversing: Use
[...items].reverse()to create a safe reversed copy with the JavaScriptreverse()method. - Use derived values when possible: Calculate a reversed display list instead of storing both original and reversed arrays in state.
- Keep stable keys: Use a unique record ID as the
keywhen you render lists in React, especially when list order changes. - Preserve API responses: Create a new display array from API data rather than changing the original response array.
- Memoize only when needed: Use
React.memoand useMemo for meaningful rendering work, not every small component.
Frequently Asked Questions
What is a Pure Component in React?
A Pure Component skips a render when its props and state have not changed according to a shallow comparison. Class components use React.PureComponent, while functional components typically use React.memo.
What is the difference between React.PureComponent and React.memo?
React.PureComponent works with class components. React.memo works with functional components and is the preferred choice for modern React projects.
Why does reverse() cause problems with React state?
The JavaScript reverse() method changes the original array. When that array is React state, direct mutation can create unpredictable UI behavior and make updates harder to track.
How do I reverse an array in React without changing the original?
Use a copied array with [...items].reverse(). You can also use items.toReversed() when your project supports it.
Can I use toReversed() in a React application?
Yes. toReversed() returns a new reversed array without changing the original array. Confirm that your target browsers and project configuration support it before relying on it.
Should I store a reversed array in React state?
Usually, no. Keep one source of truth and calculate the reversed version during rendering or with useMemo. Store a reversed array only when the reversed order represents a separate user-controlled state.
Pure Components help React avoid work when your component data stays unchanged. Use React.memo for modern functional components, keep props stable, and handle React state arrays with immutable updates. For reversed lists, create a copy before using reverse(), or use toReversed() when your browser support and project setup allow it. I hope you found this article helpful.
You May Also Like
- How to pass props in React
- How to prevent React component re-rendering
- How to fetch and display API data in React
- React conditional rendering guide
- React functional components with React.memo

Bijay Kumar is an experienced Python and AI professional who enjoys helping developers learn modern technologies through practical tutorials and examples. His expertise includes Python development, Machine Learning, Artificial Intelligence, automation, and data analysis using libraries like Pandas, NumPy, TensorFlow, Matplotlib, SciPy, and Scikit-Learn. At PythonGuides.com, he shares in-depth guides designed for both beginners and experienced developers. More about us.