Higher-Order Components in React

Pranay Chauhan
Last Updated: May 13, 2022

Introduction

Do you know why React is the most popular language for frontend developers?

React is a component-based language, meaning we can have different components coming together to display a webpage. 

This component-based architecture allows us to reuse our code in various components with the help of render props in react.

For a brief understanding, A higher-order component (HOC) is an advanced technique in React for reusing component logic.

Further, we will be discussing one exciting topic in react, i.e., higher-order components. 

Now let us get into the concept of higher-order components in react.

What are higher-order components?

A higher-order component is a pattern where a function takes a component as an argument and returns a new component.

Higher-order components are also known as HOC.

In code, it will be something like this.

const EnhancedComponent = higherOrderComponent(OriginalComponent)

Now, to understand this, let us take an example.

const IronMan = withIronSuitTonyStark )

In the above code, We have the original component as TonyStark, and withIronSuit is a function that will enhance TonyStark, and return a new component, IronMan.

Further, we will discuss the implementation of higher-order components.

Why do we need higher-order components?

To understand why we need higher-order components, we will implement a react app with two counter buttons. When we click on the button, it will display the number of times it has been clicked. 

 

The implementation will have to maintain a state variable for storing the count of how many times a button is clicked, and also, we will create a function to increment the count variable.

App.js

In App.js, we separately use the Counter1 and Counter2 components to get the functionality of buttons, as shown above.

import React from 'react';

import './App.css';

import Counter1 from './components/Counter1';

import Counter2 from './components/Counter2';

function App() {

  return (

    <div style={{textAlign:"center"}}>

      <h1>Higher-Order Components in React</h1>

      <Counter1/>

      <Counter2/>

    </div>

  );

}

export default App;

Counter1.js

We define a separate state of the Counter1 button, and it includes the state variable count and the increment count function in it. 

import React, { Componentfrom 'react'

export class Counter1 extends Component {

    state = {count:0}

    incrementCount = () => {

        this.setState({

            countthis.state.count + 1

        })

    }

    render() {

        return (

            <div>

                <button style={{color"red"fontSize:"40px"}} onClick={this.incrementCount}>

                    Clicked {this.state.count} times

                </button>

            </div>

        )

    }

}

export default Counter1

 

Counter2.js

Similar to the implementation done in the Counter1.js, The component, Counter2 also has its state variable count and the function incrementCount in it.

import React, { Componentfrom 'react'

export class Counter2 extends Component {

    state = {count:0}

    incrementCount = () => {

        this.setState({

            countthis.state.count + 1

        })

    }

    render() {

        return (

            <div>

                <button style={{color"blue"fontSize:"40px"}} onClick={this.incrementCount}>

                    Clicked {this.state.count} times

                </button>

            </div>

        )

    }

}

export default Counter2

 

 

Output

[video-to-gif output image]

 

In the naive implementation, we can observe that the code is getting repeated in Counter1.js and Counter2.js. This is not desirable and leads to a large amount of code in our codebase. This also leads to complications.

Till this point, you might be thinking that this is what we know that render props in React can solve. But it can solve this problem when we have a situation where we can have a Wrapper class, as shown below.

But what if the situation is as shown below, then we cannot use “render props.”

Therefore, In these cases, there is a need for higher-order components.

Now, we will look at the better version of implementation that uses higher-order components in react.

How to implement higher-order components?

In this implementation, we use the withCounter.js file, which contains our higher-order component. Below is the explanation of the flow of code.

App.js

From App.js, we use our Counter1 and Counter2 components.

import React from "react";

import "./App.css";

import Counter1 from "./components/Counter1";

import Counter2 from "./components/Counter2";

function App() {

  return (

    <div style={textAlign"center" }}>

      <h1>Higher-Order Components</h1>

      <Counter1 />

      <Counter2 />

    </div>

  );

}

export default App;

 

withCounter.js

This is the higher-order component, where we have an EnhancedComponent that takes in OriginalComponent and returns a NewComponent with modifications.

Also, we have state variable count and incrementCount function in this component. It is the common functionality needed by other components, namely over here Counter1 and Counter2.

import React, { Componentfrom "react";

const EnhancedComponent = OriginalComponent => {

  class NewComponent extends Component {

    state =count0 };

    incrementCount = () => {

      this.setState({

        countthis.state.count + 1,

      });

    };

    render() {

      return (

        <OriginalComponent

          count={this.state.count}

          incrementCount={this.incrementCount}

        />

      );

    }

  }

  return NewComponent;

};

export default EnhancedComponent;

 

Counter1.js

In Counter1.js, we will retrieve the props passed from withCounter component. This component will then use these props to display content.

import React, { Componentfrom "react";

import EnhancedComponent from "./withCounter";

export class Counter1 extends Component {

  render() {

    constcountincrementCount= this.props;

    return (

      <div>

        <button

          style={color"red"fontSize"40px" }}

          onClick={incrementCount}

        >

          Clicked {count} times

        </button>

      </div>

    );

  }

}

export default EnhancedComponent(Counter1);

 

Counter2.js

Similar to Counter1.js, we retrieve the props and then display them. This way, we do not need to create different state variables and functions for multiple components.

import React, { Componentfrom "react";

import EnhancedComponent from "./withCounter";

export class Counter2 extends Component {

  render() {

    constcountincrementCount= this.props;

    return (

      <div>

        <button

          style={color"blue"fontSize"40px" }}

          onClick={incrementCount}

        >

          Clicked {count} times

        </button>

      </div>

    );

  }

}

export default EnhancedComponent(Counter2);

 

 

Output

[video-to-gif output image]

 

This way, we avoided code repeatability and used higher-order components for reusing the same code for various components.

Frequently Asked Questions (FAQs)

  1. What are higher-order components?
    A higher-order component is a pattern where a function takes a component as an argument and returns a new component.
     
  2. What is the need for higher-order components?
    A higher-order component is used to improve code reusability among components. It is a more general approach than render props.
    What is the relationship between the enhanced component and the original component?
    In higher-order components, an enhanced component is an original component that is modified by a higher-order function. The higher-order component defines the relationship between them.

Key Takeaways

We learned about the concept of higher-order components in react. This is an advanced concept of React that promotes code reusability. This article also explained why there is a need for higher-order components specifically. We also learned about the implementation of higher-order components in react.

Apart from this, you can also expand your knowledge by referring to these articles on Javascript and React.

For more information about the react framework for frontend development, get into the entire Frontend web development course.

 

Was this article helpful ?
2 upvotes

Comments

No comments yet

Be the first to share what you think