Introduction
Higher-Order Components (HOCs) are a React pattern used to reuse component logic by taking one component as input and returning an enhanced component. An HOC is a function, not a React component itself. It can add features such as loading states, authentication checks, logging, or shared behavior. In this chapter, we will solve practical Higher-Order Component questions and learn how to use HOCs correctly in modern React applications. React js Higher-Order components practice questions to help you understand the concepts.
1. What is a Higher-Order Component in React?
A Higher-Order Component (HOC) is a function that takes a React component and returns a new enhanced component.
Basic structure:
function withFeature(Component) {
return function EnhancedComponent(props) {
return <Component {...props} />;
};
}
Here:
Componentis the original component.withFeatureis the HOC.EnhancedComponentis the new component returned by the HOC.
An HOC is a pattern for reusing component logic.
2. Create a Simple Higher-Order Components
Suppose we want to add a message before displaying a component.
function withMessage(Component) {
return function EnhancedComponent(props) {
return (
<div>
<p>Welcome to the application!</p>
<Component {...props} />
</div>
);
};
}
function UserProfile() {
return <h2>User Profile</h2>;
}
const EnhancedProfile = withMessage(UserProfile);
export default EnhancedProfile;
Output:
Welcome to the application!
User Profile
The HOC wraps UserProfile and adds extra behavior.
3. Pass Props Through a Higher-Order Components
An HOC should normally pass unrelated props to the wrapped component.
function withBorder(Component) {
return function EnhancedComponent(props) {
return (
<div style={{ border: "2px solid black", padding: "10px" }}>
<Component {...props} />
</div>
);
};
}
function Student({ name }) {
return <h2>Student: {name}</h2>;
}
const EnhancedStudent = withBorder(Student);
function App() {
return <EnhancedStudent name="Rahul" />;
}
export default App;
Output:
Student: Rahul
The name prop is passed through using:
<Component {...props} />
This allows the wrapped component to continue receiving its normal props.
4. Create a Loading Higher-Order Components
HOCs can be used to add reusable loading behavior.
function withLoading(Component) {
return function EnhancedComponent({ isLoading, ...props }) {
if (isLoading) {
return <h2>Loading...</h2>;
}
return <Component {...props} />;
};
}
function ProductList({ products }) {
return (
<ul>
{products.map((product) => (
<li key={product.id}>{product.name}</li>
))}
</ul>
);
}
const ProductListWithLoading = withLoading(ProductList);
function App() {
const products = [
{ id: 1, name: "Laptop" },
{ id: 2, name: "Mouse" }
];
return (
<ProductListWithLoading
isLoading={false}
products={products}
/>
);
}
export default App;
When isLoading is true:
Loading...
When isLoading is false, the original ProductList is displayed.
5. Create an Authentication Higher-Order Components
An HOC can also be used to protect a component based on authentication status.
function withAuth(Component) {
return function ProtectedComponent({ isLoggedIn, ...props }) {
if (!isLoggedIn) {
return <h2>Please log in to continue.</h2>;
}
return <Component {...props} />;
};
}
function Dashboard() {
return <h2>Welcome to Dashboard</h2>;
}
const ProtectedDashboard = withAuth(Dashboard);
function App() {
return <ProtectedDashboard isLoggedIn={true} />;
}
export default App;
If isLoggedIn is true:
Welcome to Dashboard
If it is false:
Please log in to continue.
In a real application, authentication usually comes from an authentication system or shared application state rather than a simple boolean.
6. Create a Logging Higher-Order Components
An HOC can add logging behavior without changing the original component.
function withLogger(Component) {
return function LoggedComponent(props) {
console.log("Component rendered with props:", props);
return <Component {...props} />;
};
}
function User({ name }) {
return <h2>Hello, {name}</h2>;
}
const LoggedUser = withLogger(User);
function App() {
return <LoggedUser name="Amit" />;
}
export default App;
The browser console may show:
Component rendered with props: {name: "Amit"}
The User component itself does not need to contain the logging logic.
7. Why Should an HOC Not Mutate the Original Component?
An HOC should generally wrap and compose a component instead of modifying the original component directly.
Avoid this type of approach:
function withFeature(Component) {
Component.someFeature = true;
return Component;
}
Instead, create a new component:
function withFeature(Component) {
return function EnhancedComponent(props) {
return <Component {...props} />;
};
}
This approach is safer because:
- The original component remains unchanged.
- Multiple HOCs can be used more safely.
- Component behavior is easier to understand.
- The original component can still be used independently.
The main idea is:
Original Component
↓
HOC
↓
Enhanced Component
8. Can Multiple Higher-Order Components Be Used Together?
Yes. HOCs can be composed by passing the result of one HOC into another.
function withLoading(Component) {
return function LoadingComponent({ isLoading, ...props }) {
if (isLoading) {
return <h2>Loading...</h2>;
}
return <Component {...props} />;
};
}
function withAuth(Component) {
return function AuthComponent({ isLoggedIn, ...props }) {
if (!isLoggedIn) {
return <h2>Please log in.</h2>;
}
return <Component {...props} />;
};
}
function Dashboard() {
return <h2>Dashboard</h2>;
}
const EnhancedDashboard = withLoading(
withAuth(Dashboard)
);
Now the component has both:
- Authentication behavior
- Loading behavior
This is called HOC composition.
The order can matter when HOCs perform different checks or transform props.
9. Is a Higher-Order Components the Same as a Custom Hook?
No. Both can help reuse logic, but they work differently.
A Custom Hook is a function that uses Hooks to reuse stateful logic:
function useCounter() {
const [count, setCount] = useState(0);
return { count, setCount };
}
An HOC takes a component and returns an enhanced component:
function withLoading(Component) {
return function EnhancedComponent({ isLoading, ...props }) {
if (isLoading) {
return <p>Loading...</p>;
}
return <Component {...props} />;
};
}
Main Difference
| Custom Hook | Higher-Order Component |
|---|---|
| Reuses logic inside components | Enhances a component |
| Uses Hooks | Takes component as input |
| Returns values/functions | Returns a new component |
| Common in modern function components | Common in older React patterns and some libraries |
For many new function-component applications, Custom Hooks are often the preferred way to share stateful logic, but HOCs are still useful and important to understand.
10. Build a Practical Higher-Order Components with Loading and User Data
Let’s create a practical example where an HOC adds a loading message to a user component.
import { useEffect, useState } from "react";
function withLoading(Component) {
return function EnhancedComponent({ isLoading, ...props }) {
if (isLoading) {
return <h2>Loading user...</h2>;
}
return <Component {...props} />;
};
}
function UserProfile({ user }) {
return (
<div>
<h2>{user.name}</h2>
<p>{user.email}</p>
</div>
);
}
const UserProfileWithLoading = withLoading(UserProfile);
function App() {
const [user, setUser] = useState(null);
const [isLoading, setIsLoading] = useState(true);
useEffect(() => {
const timer = setTimeout(() => {
setUser({
name: "Rahul Sharma",
email: "rahul@example.com"
});
setIsLoading(false);
}, 1500);
return () => clearTimeout(timer);
}, []);
return (
<UserProfileWithLoading
isLoading={isLoading}
user={user}
/>
);
}
export default App;
How it works
Appstarts withisLoadingset totrue.- The HOC checks the loading state.
- While loading, it displays
Loading user.... - After the data becomes available,
isLoadingbecomesfalse. - The wrapped
UserProfilecomponent is rendered. - The
userprop is passed through toUserProfile.
This example shows how an HOC can add reusable UI behavior without putting that loading logic directly inside every component.
Key Takeaways
- A Higher-Order Component (HOC) is a function that takes a component and returns an enhanced component.
- HOCs are a pattern, not a separate React feature or Hook.
- HOCs can reuse behavior such as loading, authentication, logging, and permissions.
- Pass unrelated props to the wrapped component using
{...props}. - An HOC should generally avoid mutating the original component.
- Multiple HOCs can be composed together.
- HOCs are applied like
withAuth(Profile), not rendered as<withAuth />. - Custom Hooks are often preferred for sharing stateful logic in modern function-component code.
- Each enhanced component instance can have its own state if the HOC uses state.
- HOCs remain useful for understanding existing React code and certain libraries or architectural patterns.
FAQs
1. What is a Higher-Order Components in React?
A Higher-Order Component is a function that accepts a React component and returns a new component with additional behavior or functionality.
2. Is an HOC a React component?
No. An HOC is a function that returns a React component. For example:
const EnhancedProfile = withAuth(Profile);
Here, withAuth is the HOC.
3. Can HOCs be used with function components?
Yes. HOCs can wrap function components as well as other compatible React components.
4. Should an HOC modify the original component?
Generally, no. An HOC should wrap the original component and return a new component instead of mutating the original component.
5. Are Higher-Order Components still used in modern React?
Yes, although Custom Hooks are often preferred for sharing stateful logic in modern function-component applications. HOCs are still relevant in some libraries, codebases, and existing React applications.
6. Can multiple HOCs be used on one component?
Yes. HOCs can be composed:
const EnhancedComponent = withLoading(
withAuth(Component)
);
7. What is the difference between an HOC(Higher-Order Components) and a Custom Hook?
A Custom Hook reuses stateful logic inside components and returns values or functions. An HOC accepts a component and returns an enhanced component.
Written by Shubhranshu Shekhar, who has trained 20000+ students in coding.
