The more complex your applications become, the more you will have to repeat yourself by using similar logic in various components within them. If this logic involves user authentication, API calls, and analytics collection, for example, you will be repeating yourself by not adhering to the DRY rule, which states: Higher-Order Components in React were designed to solve.
React offers several advanced patterns for code reuse. In this post, we’ll dive deep into one of the most popular classic patterns: Higher-Order Components (HOCs).
What Are Higher-Order Components in React?
A Higher-Order Component isn’t a feature baked into the React API itself it’s a pattern that emerges from React’s compositional nature. Put simply:
A Higher-Order Component is a function that takes a component as an argument and returns a new, enhanced component.

js
const EnhancedComponent = higherOrderComponent(WrappedComponent);
While a regular component transforms props into UI, an HOC transforms a component into another component with injected capabilities. It doesn’t modify the original component it wraps it.
Why Use Higher-Order Components in React?
- Cross-cutting concerns – share features like logging, authorization, or caching across entirely different components
- Props manipulation – inject new props, modify existing ones, or filter props before they reach the wrapped component
- State and logic abstraction – keep presentational components “dumb” and focused purely on rendering UI, by abstracting complex state logic into the HOC
Practical Example: The withData HOC
Say you have multiple components that need to fetch data from different API endpoints. Instead of rewriting useState and useEffect blocks in every component, you can build one reusable withData HOC.
Step 1: Creating the HOC
Here’s a function that handles fetching, loading states, and error handling: (json place holder api)
js
import React, { useState, useEffect } from 'react';
// The HOC function taking a Component and a URL string
function withData(WrappedComponent, dataUrl) {
return function WithDataComponent(props) {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
const fetchData = async () => {
try {
const response = await fetch(dataUrl);
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const json = await response.json();
setData(json);
} catch (err) {
setError(err);
} finally {
setLoading(false);
}
};
fetchData();
}, [dataUrl]);
if (loading) return <div>Loading data...</div>;
if (error) return <div>Error loading data: {error.message}</div>;
// Render the original component with the fetched data
// AND pass through any other props given to the wrapper
return <WrappedComponent data={data} {...props} />;
};
}
Step 2: Creating the Presentational Component
This component only cares about displaying a Todo item once it receives one – it doesn’t know or care how the data was fetched.
js
function TodoDisplay({ data, titleColor }) {
return (
<div>
<h2 style={{ color: titleColor }}>Todo Details</h2>
<p><strong>Title:</strong> {data.title}</p>
<p><strong>Status:</strong> {data.completed ? " Completed" : " Pending"}</p>
</div>
);
}
Step 3: Enhancing and Using the Component
Finally, wrap TodoDisplay with the HOC and render it in your app.
js
// Enhance the component
const TodoWithData = withData(
TodoDisplay,
'https://jsonplaceholder.typicode.com/todos/1'
);
function App() {
return (
<div className="App">
{/* We can still pass regular props like 'titleColor' directly to the enhanced component */}
<TodoWithData titleColor="blue" />
</div>
);
}
export default App;
Rules & Best Practices for Higher-Order Components in React
Keep these rules in mind to avoid breaking your app:
- Don’t mutate the original component. Always use composition. Inside your HOC, never modify
WrappedComponent.prototype. Treat the wrapped component as a read-only asset. - Pass unrelated props through. As shown with
{...props}above, make sure the wrapper passes down all props that aren’t specific to the HOC’s own logic. This keeps components flexible and composable. - Never create HOCs inside the render method. Avoid applying a Higher Order Component within the render() method or within the body of a functional component. When React reconciles components, it does so based on component identity. If you create a new HOC every time, React has to tear down and build up the entire tree again, which results in significant performance problems.

Also Read:- state and props in react component
Higher-Order Components vs. Custom Hooks
In modern React (v16.8+), Custom Hooks have become the preferred way to share logic.
| Feature | Custom Hooks | Higher-Order Components (HOCs) |
|---|---|---|
| Shares logic by | Reusing stateful logic directly | Wrapping components |
| Component hierarchy | Unchanged | Adds a wrapper layer |
| Best for | Most modern use cases | Layout injection, legacy integration, and complex prop manipulation |

Hook functions can handle about 90 percent of all scenarios easily, but in React there is another feature that is actually useful and it is called Higher Order Components, especially for creating wrapper components or adding layouts.
Frequently Asked Questions
Are Higher-Order Components in React still relevant with hooks available?
Yes, but whereas Custom Hooks satisfy most needs to share logic, Higher-Order Components in React can still be applied to inject layout, wrap components before rendering them, and work with old code that does not use hooks.
What’s the difference between a Higher-Order Component and a render prop?
Both are patterns to share logic between the components. The HOC takes the component and returns the component and thereby changes the component hierarchy. While the render prop pattern passes the function as the prop to a component which renders the output of the component.
Can I use multiple Higher-Order Components on the same component?
Yes, this is called composing HOCs. You can chain them, such as withAuth(withData(TodoDisplay)), though stacking too many can make debugging harder and the prop flow difficult to trace use it sparingly.
Why shouldn’t I create a Higher-Order Component inside a render method?
Since React uses reference to identify its components, creating a new HOC on each render results in the creation of a new type of component each time. As far as React is concerned, this is a totally new component, and therefore React unmounts/re-mounts the entire subtree.
Should I convert my existing Higher-Order Components in React to Custom Hooks?
Necessary or not? If the Hook Of Concern works well and doesn’t cause problems with maintenance, then there is no rush to rewrite it. For fresh code, though, Custom Hooks would typically be the easier option.
Conclusion
React Higher Order Component is still a great way of coding clear and modular architecture. The main reason is that by taking away the shared logic from your UI layer, you will have clear and well-written code.
In our next post, we will move our attention to Event Handling in React.
Also Read:- use memo vs use callback





