Frontend•Jun 2026•4 min read

Class Components vs React Hooks

Class components and hooks are two ways to write stateful React. Hooks won years ago. The only reason to touch a class today is to keep an old codebase breathing.

The short answer

React Hooks over Class Components for most cases. Hooks are the React team's official, future-facing model.

  • Pick Class Components if maintaining a legacy codebase where everything is already classes and a rewrite buys you nothing, or you need an error boundary (still class-only)
  • Pick React Hooks if writing literally any new React code. This is the default and has been for years
  • Also consider: Mixing is fine during migration — hooks and classes coexist. Just don't author NEW class components and pretend it's a neutral choice. It isn't.

— Nice Pick, opinionated tool recommendations

Code clarity and the `this` tax

Class components make you pay a this tax every single day. You bind handlers in the constructor or reach for arrow-function class fields, you read this.state and this.props everywhere, and you debug the classic 'undefined is not a function' that's really a lost binding. Lifecycle methods force unrelated concerns together — a single componentDidMount ends up handling subscriptions, fetches, and DOM measurement, while the matching teardown lives 200 lines away in componentWillUnmount. Hooks invert this. useState and useEffect let you group code by what it does, not by when React happens to call it. A subscription and its cleanup sit in one useEffect block. There's no this, no binding ritual, no constructor boilerplate. The mental model is smaller and the bug surface shrinks. Classes aren't 'wrong' here — they're just noisier for the same outcome, and that noise compounds across a real app.

Logic reuse: HOCs vs custom hooks

This is where classes genuinely lose. To share stateful logic between class components you reached for higher-order components or render props, and both wreck your tree. HOCs stack into wrapper soup — withRouter(withAuth(withTheme(Component))) — and you lose track of which prop came from which layer. Render props nest into a callback pyramid in JSX. Neither composes cleanly, and both add real DOM-less nodes that clutter React DevTools. Custom hooks make this embarrassingly simple. Extract useAuth(), useWindowSize(), useDebounce() — they're plain functions that call other hooks, return values, and add zero wrapper components. You compose them by calling them, in order, in the same flat function body. The first time you replace a three-deep HOC chain with two custom-hook calls, the argument is over. Classes had no equivalent, and the community's HOC patterns existed precisely to paper over that gap.

Migration cost and ecosystem gravity

Here's the honest part: you do not need to rip out working class components. They still render, still ship, and React has made no move to remove them. A forced rewrite is a great way to introduce bugs into code that was fine. But 'don't rewrite' is not 'keep writing.' Every new library API, every Stack Overflow answer from the last six years, every official doc example, and every tutorial assumes hooks. Concurrent features, useTransition, useDeferredValue, server-component patterns — the new toys are hook-shaped, and classes get nothing. Hiring leans the same way; a junior who learned React in 2023 may never have written a class. So the verdict isn't 'classes are broken,' it's 'classes are a maintenance dialect.' Keep the ones you have, fix them in place, and write everything new with hooks. The ecosystem's gravity points one direction, and fighting it is unpaid, unrewarded work.

The honest case for classes

I don't do 'it depends,' but I'll give classes their one real win: error boundaries. As of now there is still no hook equivalent for componentDidCatch / getDerivedStateFromError, so a class component remains the only first-party way to catch render errors in a subtree. Most teams write exactly one such boundary and never touch it again — fine, leave it a class. Beyond that, the 'classes are clearer for OOP people' argument is nostalgia, not engineering. Lifecycle methods aren't more readable; they're just familiar. And 'hooks have footguns' is true — stale closures, dependency arrays, rules-of-hooks ordering — but those are learnable rules with lint enforcement (eslint-plugin-react-hooks), not architectural dead ends. Classes had footguns too; we just stopped calling lost this bindings footguns because we'd memorized them. One error boundary aside, there is no greenfield scenario in 2026 where a class is the right call.

Quick Comparison

FactorClass ComponentsReact Hooks
Logic reuseHOCs and render props — wrapper soup, nesting, extra tree nodesCustom hooks — flat, composable, zero wrapper components
`this` binding overheadConstructor binds or class-field arrows; lost-binding bugsNo `this` at all
Code colocationLogic split across lifecycle methods by timingLogic grouped by concern in useEffect blocks
Error boundariesNative via componentDidCatch / getDerivedStateFromErrorNo hook equivalent yet — must wrap in a class
Ecosystem and future supportMaintained but frozen; new APIs ignore itDefault model; all new React features are hook-first

The Verdict

Use Class Components if: You're maintaining a legacy codebase where everything is already classes and a rewrite buys you nothing, or you need an error boundary (still class-only).

Use React Hooks if: You're writing literally any new React code. This is the default and has been for years.

Consider: Mixing is fine during migration — hooks and classes coexist. Just don't author NEW class components and pretend it's a neutral choice. It isn't.

Class Components vs React Hooks: FAQ

Is Class Components or React Hooks better?

React Hooks is the Nice Pick. Hooks are the React team's official, future-facing model. They kill `this` binding bugs, let you colocate related logic instead of scattering it across lifecycle methods, and make stateful behavior reusable without wrapper-component hell. Class components still work, but every new pattern, doc, and library example is written for hooks. Building new code on classes in 2026 is choosing the dialect React stopped speaking.

When should you use Class Components?

You're maintaining a legacy codebase where everything is already classes and a rewrite buys you nothing, or you need an error boundary (still class-only).

When should you use React Hooks?

You're writing literally any new React code. This is the default and has been for years.

What's the main difference between Class Components and React Hooks?

Class components and hooks are two ways to write stateful React. Hooks won years ago. The only reason to touch a class today is to keep an old codebase breathing.

How do Class Components and React Hooks compare on logic reuse?

Class Components: HOCs and render props — wrapper soup, nesting, extra tree nodes. React Hooks: Custom hooks — flat, composable, zero wrapper components. React Hooks wins here.

Are there alternatives to consider beyond Class Components and React Hooks?

Mixing is fine during migration — hooks and classes coexist. Just don't author NEW class components and pretend it's a neutral choice. It isn't.

🧊
The Bottom Line
React Hooks wins

Hooks are the React team's official, future-facing model. They kill `this` binding bugs, let you colocate related logic instead of scattering it across lifecycle methods, and make stateful behavior reusable without wrapper-component hell. Class components still work, but every new pattern, doc, and library example is written for hooks. Building new code on classes in 2026 is choosing the dialect React stopped speaking.

Related Comparisons

Disagree? nice@nicepick.dev