Higher-Order Components

Higher-Order Components

May The Force Be With You

Introduction

You may have encountered higher-order components in certain React applications. What are they exactly?

According to the React JS documentation, "A higher-order component (HOC) is an advanced technique in React for reusing component logic. HOCs are not part of the React API, per se. They are a pattern that emerges from React’s compositional nature." - React Higher-Order Components

In short, a higher-order component or HOC is a component that renders another component with modified properties.

Start with a simple example, we must

To kick things off, let's create a generic React component with title and body props argument.

import React from "react";
import ReactDOM from "react-dom";

const MainComponent = (props) => (
  <div>
    <h1>{props.title}</h1>
    <p>{props.body}</p>
  </div>
);

const rootElement = document.getElementById("root");
ReactDOM.render(
  <MainComponent 
    title="A long time ago.." 
    body="in a galaxy far, far away." 
  />,
  rootElement
);

Let's say our application has different components that needs to render different messages to users with different access.

One way is to add conditional rendering logic to each component that makes up our application.

However, this goes against the DRY principle.

That's where higher-order component comes in.

Some of the benefits of using higher-order components are:

  1. Control what a component will output from another component aka render hijacking
  2. Abstract and manipulate state
  3. Reuse code
  4. Manipulate props
const authenticateUser = (WrappedComponent) => {
  return (props) => (
    <div>
      <WrappedComponent {...props} />
    </div>
  );
};

const JediUser = authenticateUser(MainComponent);

const rootElement = document.getElementById("root");
ReactDOM.render(
  <JediUser
    title="I have taught you everything I know."
    body="And you have become a far greater Jedi than I could ever hope to be."
  />,
  rootElement
);

So what's exactly happening here?

First, we create a regular function, authenticateUser and pass in an argument, WrappedComponent, which will be the component that we wish to access.

Inside the authenticateUser function, we return the new component that we wish to render. That's the higher-order component.

We make use of the spread operator (...props) to pass down all the props of the parent component onto our higher-order-component.

Next we specify a new component JediUser and invoke our authenticateUser function, passing in the component that we wish to wrap (MainComponent) as the argument.

The dark side of the Force is a pathway to many abilities some consider to be unnatural.

At this current state, our higher-order component serves no real purpose other than taking one component and rendering it.

Let's take it one step further by passing a special prop into it.

const authenticateUser = (WrappedComponent) => {
  return (props) => (
    <div>
      {props.isJedi ? (
        <WrappedComponent {...props} />
      ) : (
        <p>"Someday, I will be the most powerful Jedi ever."</p>
      )}
    </div>
  );
};
const JediUser = authenticateUser(MainComponent);

const rootElement = document.getElementById("root");
ReactDOM.render(
  <JediUser
    isJedi={true}
    title="I have taught you everything I know."
    body="And you have become a far greater Jedi than I could ever hope to be."
  />,
  rootElement
);

In this new higher-order component, we use a ternary operator to conditionally render the WrappedComponent based on isJedi prop's value.

If it is true, the application will render MainComponent and if it is false, a different message will display.

Conclusion

By adding in new props to our higher-order component, we've created a versatile higher-order component that encourages code reusability.

Using this pattern, we can modify and manipulate existing React components without having to rewrite them over and over again.

We can make better use of our time to watch the Star Wars Trilogy instead.

No, not the prequels.

Latest Posts

Testing Child Component Props With React-Redux And EnzymeTesting Child Component Props With React-Redux And Enzyme
Higher-Order ComponentsHigher-Order Components
A neat JavaScript trickA neat JavaScript trick