Higher-Order Components (HOCs)

A higher-order component is a function that takes a component as input and returns a new, enhanced component that wraps it — adding shared behavior like authentication, logging, or injected data without changing the original. Names like withAuth or withLogging are the classic convention.

Learn Higher-Order Components (HOCs) in our free React course — an interactive lesson with runnable examples, a practice exercise and a quick recall.

Part of the free React course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.

1️⃣ Component In, Enhanced Component Out

An HOC is just a function. It receives a component ( Wrapped ) and returns a brand-new component that renders Wrapped with extra props or behavior. The original is never modified — you compose enhancements around it.

2️⃣ Always Forward the Props

The most common HOC bug is swallowing the props. The wrapper must spread {' '} onto the wrapped component so everything the caller passed reaches it, plus any props the HOC injects. Forget the spread and the inner component renders with nothing.

3️⃣ displayName, Guards & vs Hooks

Set Enhanced.displayName so DevTools shows the wrapping clearly. HOCs can also conditionally render — a withAuth can short-circuit to a login prompt. For most new code a custom hook is simpler, but you'll still meet HOCs like connect() in existing apps.

These lines build a complete withAuth HOC. Put them in the right order:

📋 Quick Reference

1. What goes in and what comes out of an HOC?

A component goes in; a new, enhanced component comes out. The original is never modified.

Forgetting to forward props. Always spread {' '} onto the wrapped component.

So React DevTools shows the wrapping clearly instead of "Unknown," making the tree easy to debug.

Build an HOC that injects a stamp prop, forwards the rest, and sets a readable displayName. Run it and check your output.

Practice quiz

What is a higher-order component (HOC)?

  • A component that renders other components as children
  • A built-in React hook
  • A function that takes a component and returns a new, enhanced component
  • A component with more than one root element

Answer: A function that takes a component and returns a new, enhanced component. An HOC is a function: a component goes in, and a new component that wraps it comes out.

Does an HOC modify the component it wraps?

  • No, it composes around the original, leaving it unchanged
  • Yes, it edits the original component's code
  • Only in development mode
  • Only if you pass a flag

Answer: No, it composes around the original, leaving it unchanged. The original is never modified; the HOC returns a new component that renders the original with added behavior.

What is the most common HOC bug?

  • Returning the wrong type
  • Using too many hooks
  • Not exporting the component
  • Forgetting to forward (spread) the props onto the wrapped component

Answer: Forgetting to forward (spread) the props onto the wrapped component. If you forget {...props}, the wrapped component loses everything the caller passed.

How do you forward props through an HOC?

  • Pass them one by one manually
  • Spread them: <Wrapped {...props} />
  • Use props.forward()
  • Call this.props inside the function

Answer: Spread them: <Wrapped {...props} />. Spreading {...props} onto the wrapped component passes everything through, plus any props the HOC injects.

Why set Enhanced.displayName on the returned component?

  • So React DevTools shows the wrapping clearly instead of 'Unknown'
  • To improve runtime performance
  • Because React requires it to render
  • To enable hot reloading

Answer: So React DevTools shows the wrapping clearly instead of 'Unknown'. A displayName makes the wrapping visible in DevTools, which makes the component tree easy to debug.

Where should an HOC be defined?

  • Inside the component's render so it sees fresh props
  • Inside a useEffect
  • At module scope, not inside render
  • Inside an event handler

Answer: At module scope, not inside render. Defining an HOC inside render creates a new component every render, remounting the tree and losing state. Define it at module scope.

By naming convention, an HOC that adds authentication is usually called what?

  • AuthComponent
  • withAuth
  • useAuth
  • AuthHOC

Answer: withAuth. The classic convention prefixes HOCs with 'with', e.g. withAuth or withLogging.

In modern React, what is usually preferred over writing a new HOC for shared logic?

  • A class component
  • A render prop
  • A global variable
  • A custom hook

Answer: A custom hook. A custom hook is typically cleaner and avoids deep wrapper nesting, though HOCs remain common in older codebases.

How can an HOC like withAuth render conditionally?

  • It cannot render conditionally
  • It can short-circuit, e.g. return a login prompt when there is no user
  • Only by using a useEffect
  • By throwing an error

Answer: It can short-circuit, e.g. return a login prompt when there is no user. An HOC can guard: if there is no user, it returns a login prompt instead of the wrapped component.

What problem arises from stacking many HOCs?

  • The app stops compiling
  • Props are automatically duplicated
  • 'Wrapper hell' — deeply nested wrappers that are hard to trace
  • Hooks stop working

Answer: 'Wrapper hell' — deeply nested wrappers that are hard to trace. Many stacked HOCs create deep nesting that is hard to debug; a custom hook is often a flatter alternative.