Open In App

ReactJS Higher-Order Components

Last Updated : 24 Apr, 2025
Comments
Improve
Suggest changes
Like Article
Like
Report

Higher-order components (HOC) are an advanced technique in React that is used for reusing component logic. It is the function that takes the original component and returns the new enhanced component.

  • It doesn’t modify the input component directly. Instead, they return a new component with enhanced behavior.
  • They allow you to reuse component logic across multiple components without duplicating it.
  • They are pure functions that accept a component and return a new component.

Syntax:

const EnhancedComponent = higherOrderComponent(OriginalComponent);

In this syntax:

  • higherOrderComponent is a function that takes an existing component (OriginalComponent) as an argument.
  • It returns a new component (EnhancedComponent) with additional functionality or behavior.
  • The EnhancedComponent behaves like the original component but with enhanced features provided by the HOC.

Implementation of the Higher-Order Components

Step 1: Create a React application

Create a React application by using the following command.

npm create vite@latest foldername
  • where foldername is the name of your project. You can change it to any name you prefer.
  • npm create vite@latest foldername: This command initializes a new Vite project with a React template. Replace foldername with your desired project name.

Step 2: Move in the Folder

After creating your project folder i.e. foldername, move to it using the following command.

cd foldername

Project Structure:

Project-Structure
Project Structure

Example 1: Let say, we need to reuse the same logic, like passing on the name to every component.

Name.js
import React from 'react';
// Higher-Order Component (HOC) as a functional component
const withName = (OriginalComponent) => {
  const NewComponent = (props) => {
    return <OriginalComponent {...props} name="GeeksforGeeks" />;
  };
  return NewComponent;
};
export default withName;
App.js
import React from "react";
import "./App.css";
import withName from './Components/Name'; // Import the HOC
// Functional component
const App = (props) => {
  return <h1>{props.name}</h1>;
};
// Wrap the App component with the HOC to create the enhanced version
const EnhancedComponent = withName(App);
// Export the enhanced component
export default EnhancedComponent;

Output:

In this example:

  • HOC Definition: withName is a Higher-Order Component (HOC) that adds a name prop with the value "GeeksforGeeks" to any component passed into it.
  • Original Component: The App component simply renders the name prop inside an <h1> element.
  • Applying the HOC: In App.js, the App component is passed to the withName HOC, creating a new component, EnhancedComponent.
  • Enhanced Component: The EnhancedComponent now has the name prop and will display "GeeksforGeeks" when rendered.
  • Export: The EnhancedComponent is exported and used to display the final output in the browser.

Example 2: In this example let's implement some logic. Let's make a counter app. In HighOrder.js, we pass the handleclick and show props for calling the functionality of the component.

App.css
body {
  margin: 0;
  font-family: sans-serif;
  background: #f0f4f8;
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100vh;
}

.container {
  background: #ffffff;
  padding: 40px;
  border-radius: 16px;
  box-shadow: 0 8px 16px rgba(0, 0, 0, 0.1);
  text-align: center;
}

.title {
  margin-bottom: 20px;
  font-size: 1.8rem;
  color: #333;
}

.count {
  font-size: 4rem;
  color: #007bff;
  margin-bottom: 20px;
}

.buttons {
  display: flex;
  gap: 12px;
  justify-content: center;
}

.btn {
  font-size: 1.5rem;
  padding: 10px 16px;
  border: none;
  border-radius: 8px;
  background-color: #007bff;
  color: white;
  cursor: pointer;
  transition: 0.3s;
}

.btn:hover {
  background-color: #0056b3;
}

.reset {
  background-color: #ff4d4f;
}

.reset:hover {
  background-color: #d9363e;
}
withCounter.jsx
// src/components/withCounter.jsx
import React, { useState } from 'react';
const withCounter = (WrappedComponent) => {
  return function WithCounter(props) {
    const [count, setCount] = useState(0);

    const increment = () => setCount((prev) => prev + 1);
    const decrement = () => setCount((prev) => prev - 1);
    const reset = () => setCount(0);
    return (
      <WrappedComponent
        count={count}
        increment={increment}
        decrement={decrement}
        reset={reset}
        {...props}
      />
    );
  };
};

export default withCounter;
Counter.jsx
// src/components/Counter.jsx
import React from 'react';
import '../App.css';

const Counter = ({ count, increment, decrement, reset }) => {
  return (
    <div className="container">
      <h2 className="title">Counter App</h2>
      <div className="count">{count}</div>
      <div className="buttons">
        <button onClick={increment} className="btn">+</button>
        <button onClick={decrement} className="btn">-</button>
        <button onClick={reset} className="btn reset">Reset</button>
      </div>
    </div>
  );
};

export default Counter;
App.jsx
// src/App.jsx
import React from 'react';
import withCounter from './components/withCounter';
import Counter from './components/Counter';
import './App.css';

const EnhancedCounter = withCounter(Counter);
const App = () => {
  return <EnhancedCounter/>;
};
export default App;
index.js
// src/index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<App />);

Output:

Animationkk
ReactJS Higher-Order Components

In this example:

  • App.jsx: The App component imports and uses the EnhancedCounter, which is the Counter component wrapped by the withCounter HOC to add counter logic.
  • index.js: It renders the App component to the root DOM element using ReactDOM.createRoot.
  • withCounter.jsx: The withCounter HOC takes a component (WrappedComponent) and adds state logic (increment, decrement, and reset) for counting.
  • Counter.jsx: The Counter component displays the current count and provides buttons to increment, decrement, or reset the counter value.
  • State Management: The withCounter HOC uses useState to manage the count and passes the count and its control functions as props to the Counter component.

Reason to Use Higher-Order Components

  • Code Reusability: HOCs allow you to reuse logic across multiple components without repeating the same code in each one.
  • Separation of Concerns: They help separate the logic and UI, making components easier to manage and maintain.
  • Enhances Readability: By abstracting shared logic into HOCs, your components remain clean and focused solely on rendering UI.
  • Easy to Maintain: Centralizing shared behavior in a HOC reduces code duplication, making it easier to fix bugs and add new features.

Best Practices for Using (HOC)

  • Don’t Overuse HOCs: Use HOCs only when necessary. Too many HOCs can make your code complex and harder to manage.
  • Use for Reusable Logic: HOCs are good for adding common features (like authentication or loading states) across multiple components.
  • Pass All Props: Make sure the HOC passes all the props from the original component to the new one, unless you specifically want to modify or add something.
  • Name Components Clearly: Always give meaningful names to wrapped components, which helps in debugging and readability.

Conclusion

Higher-Order Components (HOCs) are a powerful tool in React for reusing component logic and enhancing components without changing their original behavior. By wrapping a component with an HOC, you can add extra functionality such as authentication, data fetching, or logging.


Next Article

Similar Reads