A Higher-Order Component is a React pattern for reusing component behavior. An HOC is a function that receives a component and returns another component with additional behavior. HOCs were widely used before Hooks and are still important to understand because many mature React codebases contain them.
What is an HOC?
An HOC is a function that takes a component and returns an enhanced component. It is a pattern for component composition, not a special React API.
function withLogging(WrappedComponent) {
return function EnhancedComponent(props) {
console.log("Rendering component");
return <WrappedComponent {...props} />;
};
}
Basic HOC flow
flowchart LR
A[Original component] --> B[HOC function]
B --> C[Enhanced component]
C --> D[Additional behavior]
C --> E[Original UI]
Authentication HOC
An authentication HOC can check whether the user is authenticated before rendering the protected component. In a real application, authentication state would normally come from an established auth context or application state.
function withAuth(Component) {
return function ProtectedComponent(props) {
const isAuthenticated = true;
if (!isAuthenticated) {
return <p>Please sign in</p>;
}
return <Component {...props} />;
};
}
const ProtectedDashboard = withAuth(Dashboard);
Passing props through an HOC
The wrapper should normally pass the received props to the wrapped component unless the HOC intentionally transforms them.
function withLoading(Component) {
return function LoadingWrapper({ loading, ...props }) {
if (loading) {
return <p>Loading...</p>;
}
return <Component {...props} />;
};
}
Adding injected props
An HOC can calculate information and provide it to the wrapped component. This pattern should be documented clearly because the wrapper changes the component's expected props.
function withUser(Component) {
return function UserWrapper(props) {
const user = { id: 10, name: "Ravi" };
return <Component {...props} user={user} />;
};
}
Do not mutate the original component
A good HOC creates a wrapper instead of modifying the original component. Mutating the component can create unexpected behavior when the same component is used elsewhere.
Static properties
Wrapping a component can hide static properties attached to the original component. If a legacy codebase depends on static properties, the HOC may need a deliberate strategy to preserve or hoist them.
Ref forwarding consideration
A normal prop named ref has special React behavior. Older HOC patterns sometimes used ref forwarding so that a parent could reach the underlying component. Modern React versions and APIs have evolved, so follow the ref behavior supported by the React version used by the application.
HOC composition
const Enhanced = withAuth(
withLogging(
withLoading(Dashboard)
)
);Multiple wrappers can become difficult to read. This is one reason Hooks and component composition are often preferred in newer React code.
HOC vs Custom Hook
| Pattern | Main idea | Typical use |
|---|---|---|
| HOC | Enhance a component by wrapping it | Legacy reusable component behavior |
| Custom Hook | Reuse stateful logic | Modern function component logic |
| Component composition | Combine components directly | Reusable UI structure |
Where HOCs still appear
You may encounter HOCs in older applications, libraries, permission systems, analytics wrappers, routing integrations, and component libraries. Knowing the pattern helps you read and maintain existing code even if you choose Hooks for new code.
Common mistakes
- Mutating the wrapped component.
- Forgetting to pass props.
- Creating deeply nested wrapper trees.
- Hiding important behavior inside many layers.
- Using an HOC when a simpler custom hook or composition pattern is clearer.
Interview questions
- What is a Higher-Order Component?
- Is HOC a React API?
- Why should an HOC avoid mutating the original component?
- How do you pass props through an HOC?
- HOC vs custom hook?
- Where might you find HOCs in an existing application?
Key takeaways
- An HOC is a function from component to enhanced component.
- It is a composition pattern.
- Props should normally be passed through deliberately.
- Hooks are usually a clearer choice for new reusable logic in function components.