What are higher-order components (HOCs) in React?
React is a popular JavaScript library for building user interfaces. One of its powerful features is Higher-Order Components (HOCs), which allow us to enhance and reuse component logic.
Higher-order components (HOCs) are functions that take a component as an argument and return a new component with extended functionality. They act as wrappers around existing components, enhancing them with additional props, states, or behavior. HOCs are not React components themselves; they are functions that return components.
A HOC is a pure function. It has no side effects, it returns a new component.
Syntax
The general syntax for creating a higher-order component (HOC) is as follows:
const HigherOrderComponent = (WrappedComponent) => {// Define and return the Enhanced Componentreturn class EnhancedComponent extends React.Component {// Add additional logic, state, or behavior hererender() {// Render the Wrapped Component with modified or additional propsreturn <WrappedComponent {...this.props} />;}};};
Explanation
Lines 1–3:
HigherOrderComponentis the HOC function that takes aWrappedComponentas its argument. It returns a new class component (EnhancedComponent) that wraps the original component and provides extended functionality.Lines 6–8: The
WrappedComponentis rendered within theEnhancedComponentby passing down the original props using the spread operator ({...this.props}). This ensures that the wrapped component receives the necessary props, either unmodified or with any modifications or additions made by the HOC.
How do higher-order components work?
When you invoke a higher-order component, it creates a new component that wraps the previous component and adds new features to it. Props are received by the HOC, modified if necessary, and passed down to the wrapped component. This allows the HOC to reuse code and give common functionality into several components.
We do not alter or mutate components: we make new ones.
Advantages of higher-order components
Reusability: HOCs promote code reusability by
common logic that can be applied to multiple components.encapsulating The process of wrapping up variables and methods into a single entity is known as Encapsulation. Separation of concerns: By separating the concerns of your application into different HOCs, you can achieve cleaner and more maintainable code.
Code organization: HOCs help in organizing code by extracting shared functionality and keeping it in one place.
Cross-cutting concerns: HOCs are ideal for handling
such as authentication, logging, and data fetching, as they can be easily applied to multiple components.cross-cutting concerns Cross-cutting concerns are parts of a program that rely on or must affect many other parts of the system.
Implementation
To have a clear understanding of how to create and use HOCs to extend the functionality of your components, let's explore one example.
Creating higher-order component
import React from 'react';const withLogger = (WrappedComponent) => {return class extends React.Component {componentDidMount() {console.log(`Component ${WrappedComponent.name} mounted.`);}componentWillUnmount() {console.log(`Component ${WrappedComponent.name} unmounted.`);}render() {return <WrappedComponent {...this.props} />;}};};export default withLogger;
Explanation
Line 3: This line defines a higher-order component function called
withLogger. It takes a single argumentWrappedComponent, which represents the component that will be wrapped or enhanced by the HOC.Line 4: Here, we define an
within theanonymous class component An anonymous class component in React is a class component that is defined without assigning it a specific name. withLoggerHOC function. This new component is the enhanced component that will be returned by the HOC.Lines 5–7: This method is a lifecycle method called
componentDidMountthat is invoked when the component is to themounted Mounting is the initial phase in which the instance of the component is created and inserted into the DOM . In this example, it logs a message to the console indicating that the wrapped component has been mounted. TheDOM ReactDOM is used to render components and elements on the web. WrappedComponent.nameretrieves the name of the wrapped component.Lines 9–11: This method is also a lifecycle method called
componentWillUnmountthat is invoked when the component is about to be from the DOM. It logs a message indicating that the wrapped component is being unmounted.unmounted The unmounting phase occurs when a component is about to be removed from the DOM. Lines 13–15: The
rendermethod returns the wrapped component, passing down all the props using the spread operator ({...this.props}). This ensures that the wrapped component receives its original props, allowing seamless integration of the enhanced functionality provided by the HOC.
Using the higher-order component
Create a simple functional component called HelloWorld that displays a greeting.
const HelloWorld = () => {return <div>Hello, World!</div>;};
Wrap the HelloWorld component with the withLogger HOC.
const EnhancedHelloWorld = withLogger(HelloWorld);
Replace the existing JSX code in the return statement of the App component with the EnhancedHelloWorld component.
function App() {return (<div className="App"><EnhancedHelloWorld /></div>);}
Output
Conclusion
Higher-order components (HOCs) are a useful tool for code reuse, separation of concerns, and code organization in React. They allow us to encapsulate and extend component functionality without altering their original implementation. You can extract similar logic and apply it to numerous components by creating HOCs, resulting in cleaner and more maintainable code.
Free Resources