REACT Higher-Order Component

What is a Higher-Order Component (HOC)?

A Higher-Order Component (HOC) is a function that takes a component as input and returns a new enhanced component. HOCs allow code reuse, logic abstraction, and component composition in React.

HOCs follow this pattern:

const EnhancedComponent = withSomething(OriginalComponent);

Try It Now

1. Why Use HOCs?

  • Code Reusability: Extract shared logic into a single function.
  • Separation of Concerns: Keep components focused on UI while HOCs handle logic.
  • Enhancing Components: Add features like authentication, theming, logging, etc.

2. Basic Example of an HOC

Let’s create an HOC that adds extra props to a component.

Step 1: Create the HOC

import React from "react";

const withExtraInfo = (WrappedComponent) => {
  return (props) => {
    return <WrappedComponent extraInfo="This is extra info!" {...props} />;
  };
};

export default withExtraInfo;

Try It Now

Step 2: Use the HOC in a Component

import React from "react";
import withExtraInfo from "./withExtraInfo";

const MyComponent = ({ extraInfo }) => {
  return <h1>{extraInfo}</h1>;
};

export default withExtraInfo(MyComponent);

Try It Now

βœ… What happens? The MyComponent now automatically receives extraInfo from the HOC.

3. Practical Use Cases of HOCs

A. Authentication HOC (Protect Routes)

const withAuth = (WrappedComponent) => {
  return (props) => {
    const isAuthenticated = true; // Simulating authentication

    if (!isAuthenticated) {
      return <h2>Please log in to access this page.</h2>;
    }

    return <WrappedComponent {...props} />;
  };
};

// Usage:
const Dashboard = () => <h1>Welcome to Dashboard</h1>;
export default withAuth(Dashboard);

Try It Now

B. Logging HOC (Track Component Rendering)

const withLogger = (WrappedComponent) => {
  return (props) => {
    console.log(`Component ${WrappedComponent.name} is rendering`);
    return <WrappedComponent {...props} />;
  };
};

// Usage:
const Profile = () => <h1>My Profile</h1>;
export default withLogger(Profile);

Try It Now

Every time Profile renders, it logs to the console!

 

C. Fetch Data HOC

import React, { useEffect, useState } from "react";

const withDataFetching = (url) => (WrappedComponent) => {
  return (props) => {
    const [data, setData] = useState(null);

    useEffect(() => {
      fetch(url)
        .then((res) => res.json())
        .then((data) => setData(data));
    }, []);

    return data ? <WrappedComponent data={data} {...props} /> : <h3>Loading...</h3>;
  };
};

// Usage:
const UsersList = ({ data }) => (
  <ul>
    {data.map((user) => (
      <li key={user.id}>{user.name}</li>
    ))}
  </ul>
);

export default withDataFetching("https://jsonplaceholder.typicode.com/users")(UsersList);

Try It Now

The UsersList component automatically gets user data!

4. HOCs vs. Render Props vs. Hooks

Feature HOCs Render Props Hooks
Code Reuse βœ… Yes βœ… Yes βœ… Yes
Readability ❌ Can get messy βœ… Better βœ… Best
Performance ⚠️ Can cause re-renders βœ… More control βœ… Efficient
Modern React 🚫 Less recommended βœ… Okay βœ… Best choice

πŸ‘‰ Hooks (like useEffect, useContext) have mostly replaced HOCs in modern React, but HOCs are still useful in class-based components!

5. When to Use HOCs?

βœ… Use HOCs when:

  • You need to reuse logic across multiple components.
  • Your project uses class components.
  • You want to abstract complex logic (e.g., authentication, permissions, logging).

❌ Avoid HOCs when:

  • You are using modern React with hooks (useEffect, useContext).
  • You have only a single-use case (directly placing logic in the component may be simpler).