When Should You Use Class, Functional, or Pure Components in React?
This article explains the differences between React class components, functional (stateless) components, and PureComponent, shows their source code, discusses shallow equality checks, introduces the memo higher‑order component, and provides practical guidelines for choosing the right component type to improve performance.
1 Class Component vs Functional Component
React defines two component types: class components and functional components.
1.1 Class Component
Example:
<code>class Welcome extends React.Component {
render() {
return <h1>Hello, {this.props.name}</h1>;
}
}</code>1.2 Functional Component
Example:
<code>function Welcome(props) {
return <h1>Hello, {props.name}</h1>;
}</code>1.3 Stateless Component
Functional components are also called stateless components because they have no state or lifecycle methods and only receive props to render DOM.
Only receive props and render DOM
No state
Cannot access lifecycle methods
No class declaration needed, syntax is simpler
Cannot be directly instantiated; ref must be wrapped with React.forwardRef
No need to bind this
Better performance due to lack of lifecycle management
Stateless components are suitable for very small UI pieces where re‑render cost is low.
2 Class Component vs Pure Component
2.1 Class Component
Lifecycle method
shouldComponentUpdatereturns a boolean. By default it returns true, causing updates when props or state change.
2.2 Pure Component
A component is pure when its output depends only on its inputs and is the same for identical inputs. React provides
PureComponentwhich performs a shallow equality check on props and state.
Source code shows
Componentbase class and
PureComponentextending it, adding
isPureReactComponent. The scheduler uses this flag to decide whether to run a shallow comparison via
shallowEqual.
<code>function shallowEqual(objA, objB) {
if (Object.is(objA, objB)) return true;
if (typeof objA !== 'object' || objA === null ||
typeof objB !== 'object' || objB === null) {
return false;
}
const keysA = Object.keys(objA);
const keysB = Object.keys(objB);
if (keysA.length !== keysB.length) return false;
for (let i = 0; i < keysA.length; i++) {
if (!Object.prototype.hasOwnProperty.call(objB, keysA[i]) ||
!Object.is(objA[keysA[i]], objB[keysA[i]])) {
return false;
}
}
return true;
}</code>Shallow comparison is not suitable for nested objects.
Pure components reduce unnecessary renders, improving performance especially in large component trees.
2.3 Pure Functional Component
Since React 16.6, the
memohigher‑order component can give a functional component the same render‑control benefits as
PureComponent.
<code>import React, { memo } from 'react';
const ToTheMoonComponent = React.memo(function MyComponent(props) {
// only renders if props have changed
});</code> memomemoizes the rendered output and skips rendering when props are unchanged.
3 Guidelines
Use stateless components when no state is needed.
Prefer pure components when possible.
Performance order: stateless functional > class components > React.createClass().
Minimize props passed to a component.
Extract components that contain complex conditional logic.
Avoid premature optimization; make components reusable for current needs.
QQ Music Frontend Team
QQ Music Web Frontend Team
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.