React: Functional, Class, and Pure Components

A good React app is built from components with clear jobs. A component might render a small part of the interface, hold state, or bring several other components together; useful boundaries make those pieces easier to understand and reuse.
One of the main concepts behind successful and efficient React development is reusable components that you can swap in and out, a little like LEGO pieces. In a similar way to having a separation between presentation and structure when developing with CSS and HTML, it's a great idea to keep your functional React logic far, far away from the components that render the UI for your users.
However, there are a few options for separating logic and rendering when it comes to React ‑ and optimising React involves picking the right component type for the job. So, what are your options, and when should you use them?

What are Class Components?
Class components were once the standard way to give a component local state and lifecycle methods. They receive props and may own state, but a class is not necessarily stateful: it can also render entirely from its props.
For example, a simple component defined using an ES6 class:
class HellowWorld extends React.Component {
render() {
return <p>Hello, {this.props.planet}</p>;
}
}A class component might fetch information and update local state through its lifecycle methods. That was the established model before Hooks, but the class syntax does not make the component inherently heavy; the cost depends on the work performed, its render tree and how often updates occur.
When Should You Use a Functional Component?
Function components are functions that return React elements. Since Hooks arrived in React 16.8, they can own state, run effects and compose reusable logic; "stateless" describes a particular component, not the function‑component category.
In simplest terms, and in its simplest form, a functional component just outputs some markup. For example:
function App() {
const greeting = 'Hello World';
return <p>{greeting}</p>;
}A function component is a good fit for a ListItem that renders from props within a List component, and Hooks allow the same form to grow when it genuinely needs state or an effect. It normally renders when its parent renders and can also render for its own state or context updates; the syntax does not prevent those updates.

How Should You Use Pure Components?
React.PureComponent is a class optimisation for a specific case. A normal function component and a normal class component both render when their parent renders. PureComponent may skip a class render when shallow comparison finds its props and state unchanged; React.memo provides a related option for function components.
React.PureComponent implements a shallow comparison of both props and state in shouldComponentUpdate. It still supports the class lifecycle; extending it does not make a component functionally pure or automatically faster. The comparison is worthwhile only when the skipped rendering costs more than the comparison and the data follows immutable update patterns.
class PureHelloWorld extends React.PureComponent {
render() {
const { hello, world } = this.props;
return (
<p>{hello} {world}</p>
)
}
}The shallow comparison checks top‑level references. Nested data is still passed and used, but mutating it in place can leave the top‑level reference unchanged and cause PureComponent to skip a needed render. Replace changed objects and arrays rather than mutating them.

Wrapping Up
Start with the component's job and the code you're maintaining. Function components with Hooks are a useful default for new work, whilst an existing class may be perfectly sensible to keep. Changing the syntax alone does not make the work cheaper to render.
Choose a function or class component for its API and maintenance context, not because one is intrinsically pure. A ListItem that always renders the same output for the same inputs is a candidate for memoisation, but add PureComponent or React.memo only after identifying avoidable renders and keep prop references stable enough for shallow comparison to be meaningful.