DEV Community

Cover image for Introduction to Higher Order Components(HOCs)In React
Johnson Ogwuru
Johnson Ogwuru

Posted on • Edited on

Introduction to Higher Order Components(HOCs)In React

The past week got me learning a lot of things, a lot of concepts I would really love to share. I would begin by discussing Higher-order functions(HOCs) In react.

To be able to understand Higher order components in react, we would first need to understand what Higher Order functions are in JavaScript. Higher-order functions in Javascript are functions that take other functions as arguments and return another function. Examples of the higher-order functions are the; .map, .filter, etc. Some of them I wrote about in this article:

It’s important to note that I’m assuming you have prior knowledge of React if you don’t below is an awesome tutorial by traverse media.
That aside let’s jump right in.

Higher Order Components are components that take as argument another component or components and returns a new component. Could be likened to a Higher Order function, well that’s where the name came from. It is an advanced technique in react for re-using the logic of a component. HOC’s could be used when we want to abstract a login component from the other components in a site, and I would demonstrate how. HOCs are commonly used as advanced react patterns for designing some components that share certain behaviors in a way that makes them connected differently than just the normal state-> props pattern. HOCs as an advanced react pattern allows us the capability of reusing component logic. Think about the functionality of the login component I mentioned. The login could be just a form that takes as value a username, and password and performs a check against a database or any storage means if the user exists on the system. if the user does, and the password entered is correct, then the App component would render the content component, but if the user doesn’t exist, the App renders the login component, the same could be applied to when checking if a user on the site still has a valid authentication. This example could be performed using a Higher-order component. But how, the code below demonstrates how.

Say we have an App component as such

   import React, { Component } from 'react'

   //below is the app component that would render to the DOM
   export default class App extends Component {
     render() {
       return (
          <div>
            <h1> Hello world </h1>
          </div>
       )
     }
   }
Enter fullscreen mode Exit fullscreen mode

To create a higher order component that would perform the function we want, which is determining which component to render depending on the status of the user's login session, we would first have to create the two components.

Please note, to make this explanation as simple as it could possibly get, I would be creating all of the components inside the app.js file. And also we would be making use of create-react-app, please get it set up

Below, we would be creating both the login and content components, both are actually going to be dummy components simply calling out their names in an h1 tag.

   import React, { Component } from 'react'

   // Login Component
   export default function Login {
      return (
         <div>
           <h1>Hi i'm login</h1>
         </div>
      )
   }

   //Content component
   export default function Content {
       return (
          <div>
            <h1>Hi i'm Content</h1>
          </div>
       )
   }

   //App component
   export default class App extends Component {
     render() {
       return (
          <div>
            //Add component to render here
          </div>
       )
     }
   }
Enter fullscreen mode Exit fullscreen mode

Having built out the individual components, it's time for us to create our HOC.

Please note that you can choose to create this in a different file, but to make this article simple and straight to the point, I would be doing everything from a single file.

Copy and paste the following code immediately under the Content component and before the App component.

  const withAuthentication = Component1 => Component2 =>
     class extends Component {
       constructor(props) {
         super(props);
         this.state = {
          isLoggedin: false,
         };
       }

       render(){
          if(this.state.isLoggedin) {
            return <Component1 />
          } else {
            return <Component2 />
          }

       }
Enter fullscreen mode Exit fullscreen mode

The above is as simple as a Higher-order Component can be.

It's of vital importance that we note how HOCs are named, it's generally accepted that they are named starting with with and then whatever their specific job is, In our case authentication. That way anyone looking at your code knows it's a Higher-order component without looking at the code, this is especially very important where the HOC leaves in a separate file.

To explain the code. We use what is being referred to as curring in JavaScript to receive the arguments supplied to a HOC. Currying was what we did when we passed the two arguments to the HOC as so; Component1 => Component2 =>, which is actually equivalent to us declaring a method and passing an argument to it, the normal Javascript way.

Further down, the HOC returns an anonymous class which has a state object, that houses the isLoggedin property, which you would manipulate however you want, during the course of developing your application, to determine when a user is logged in and when they are not.

Further down to the render() method, we add a condition to check the state for the value of isLoggedin, so whatever the value is a Component is being returned respectively.

Now, the question in your mind could obviously be how you can get to use this. Pay close attention. Copy and paste the following code immediately under the HOC withAuthentication() we just wrote.

  const DoAuthenticate = withAuthentication(Content, Login);
Enter fullscreen mode Exit fullscreen mode

Now by assigning our HOC withAuthenticate to a function DoAuthenticate, we are setting whatever the returned function inside of HOC to DoAuthenticate who from how it's named, shows it's a component.

Because of how our HOC was organized, we need to make sure the Content component stays at the position of Component1 in the HOC because we expect it to be returned when the user is logged and the Login component taking the position of Component2 as defined in the HOC.

Now instead of having to wonder which Component to render to the DOM through the App Component, we just render the DoAuthenticate and allow the HOC do the pondering over for us. In the end, our code should look like so.

   import React, { Component } from 'react'

   // Login Component
   export default function Login {
      return (
         <div>
           <h1>Hi i'm login</h1>
         </div>
      )
   }

   //Content component
   export default function Content {
       return (
          <div>
            <h1>Hi i'm Content</h1>
          </div>
       )
   }


   // Higher order Component
   const withAuthentication = Component1 => Component2 =>
     class extends Component {
       constructor(props) {
         super(props);
         this.state = {
          isLoggedin: false,
         };
       }

       render(){
          if(this.state.isLoggedin) {
            return <Component1 />
          } else {
            return <Component2 />
          }

       }


   const DoAuthenticate = withAuthentication(Content, Login);

   //App component
   export default class App extends Component {
     render() {
       return (
          <div>
            <DoAuthenticate />
          </div>
       )
     }
   }
Enter fullscreen mode Exit fullscreen mode

Learning about HOCs was really fun for me and I made two applications during the week, to deepen my understanding of it. Here are links to the applications.

Instaclone a clone of the Instagram application(not a complete clone though...lol) and LambdaTimeX. Would be dropping links to they Repos on the comment section.

To further your knowledge, I would recommend you give this article on HOCs by Sitepen a shot. 🥂🥂🥂🥂

Top comments (9)

Collapse
 
anpos231 profile image
anpos231 • Edited

I use HOC to separate logic from view.
Imagine you have component that allows users to select an item from a list.

I'd split it like this:
Functional component which is used to render the component.
Class component which holds logic/state for that component.

SelectLogic is a HOC for SelectView. Of course both components are replaceable, so you can switch Login/View depending on the needs.

Collapse
 
ogwurujohnson profile image
Johnson Ogwuru

That's okay too

Collapse
 
monfernape profile image
Usman Khalil

I just can't understand HOC. We can use custom components for reusable code and logic, can't we?

Collapse
 
ogwurujohnson profile image
Johnson Ogwuru

Sorry for the late response. Yes, but most times I actually use HOCs for determining which components should be rendered. Like choosing when to render a login component or an error page component

Collapse
 
monfernape profile image
Usman Khalil

Just spend last few days with HOC and I understand your point now. Thank you John

Thread Thread
 
ogwurujohnson profile image
Johnson Ogwuru

I'm happy you understand it now.. Cheers

Collapse
 
isaacbatst profile image
Isaac Batista

Hello i'm new in this topic, and I thinking if is there any difference from doing like this example or just literally importing 2 components inside my main component and render conditionally one or another.

Collapse
 
10secondsofcode profile image
Elango Sundar

@johnson Nicely explained the HOC Functions & components. Another doubt how to publish this types of HOC into npm .

Collapse
 
ogwurujohnson profile image
Johnson Ogwuru

If I get what you mean, I haven't really given it a shot, so I can't say