React’s Higher-Order Components (HOCs)
Understand React HOCs with the help of a use case
In simple terms, a higher-order function is one that takes a function as an input parameter or returns a new function as output. In the context of React, higher-order components (HOCs) are the components that take a component as input and return another component as output.
React 16.8 introduces the concept of higher-order components. A HOC is an advanced technique for reusing the component logic. HOCs are not part of some React APIs, but the concept emerges from the compositional nature of React. Composition refers to containing one component within another.
The composite nature of React allows us to create components containing further sub-components. The simple example of composition would be a simple web page containing multiple components like
<NavigationComponent />, and
<ContentContainer />. All these components combine together to form a single web page.
React has extended the functionality further so that the components can take one component as input or return some components as output.
Details on composition are available in the React article “Composition vs. Inheritance.”
Adding Functionality to Existing Components
Higher-order components focus on extending the functionality of the existing component. It takes a component as input and returns a new component that wraps the input component passed as a parameter. The wrapper may provide some additional data or functionality to the original component taken as the input.
Ensuring Reusability of Code
When we are working with multiple components in our application, there might be scenarios where some part of the component is reusable (for example, making an asynchronous data call). Higher-order components aim to extract the common part of the code as a part of the wrapper component, which can be reused by other components.
Working With Sample Code
Use case scenario
Let me try explaining the use case with the help of a simple scenario:
We have two components for an employee management application. Each component needs to render some employee data. Data required for both components are available from the same logic/function. Both components need to invoke the common function for data.
Now keeping the above scenario in mind, let's see how we can resolve the required use scenario, ensuring that we can share the common logic.
Employee basic details component
This is the first component required for the application. It displays the basic details of employees. The code given above creates a simple functional component that takes the employee details as an input
props parameter and displays employee’s basic details (
designation). So the input
props should have the specified props properties.
Employee salary details component
We are creating another component (specified above) that displays the salary-related employee information to the user. This functional component takes a
props parameter as input and displays salary-related information to the user (
Common logic/function for employee details
Both these components are expecting an object literal containing required fields.
<ShowEmployeeBasicDetails /> component expects name, age, and designation properties to be made available in the
props object. And
<ShowEmployeeSalaryDetails /> component expects salary and bonus properties as a part of the
Given above is a single function which fetches the details that are required by both of the components. It contains all the required fields.
Resolving the issue with HOCs
Since the data required by both the components are available from a single function call, we can reuse the code to fetch the data for both components. The reusable code can be segregated as a separate wrapper component to which our main components can be passed as a parameter. This wrapper component provides extra functionality to fetch the data and provide this data to any component which is passed as a parameter. (
ShowEmployeeSalaryDetails). The wrapper function is referred to as a higher-order component.
In the code above, we have created a function
higherOrderComponent that takes a component as input and returns another component. When the returned component is rendered, the constructor function performs the common task of fetching the common data for the components. The data is provided to the wrapped components as
Recap and Conclusion
Let me explain again.
ShowEmployeeSalaryDetails components are passed as input to the wrapper component. These wrapped components expect the
props data. The constructor specified in the wrapper function makes function calls to fetch data and saves the data to the state variable, and this data is made available to the components. Thus we reduce the code since both of the components do not need to have separate code for data fetching in each component.
Higher-order components provide an excellent way to wrap common functionalities in a single wrapper component and make them available to the wrapped component (components passed as a parameter).
I hope the article was able to provide clarity regarding the basics of higher-order components. Thanks!
Below is the working code on the Fiddler: