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.