Higher Order Component
Tags: javascript, react, webdev, beginners
Published: 2024-05-10 14:02:59

Higher Order component is a function that takes a component and returns a component. At the end of the day it's just a normal function. 

- Why do we use it ? 
- When do we use it ?
- What component does it take ?
- What component does it returns ?

Let me tell you the theory behind it. So, a higher-order component takes a component as input, enhances that component, adds some extra features to the component, and returns it. Still don't make any sense? Okay, I'm holding your hand and walking you through by example.

<br>

**Example:** From my movie list, I want to add a `New 🌱` label to specific movie cards. Does it sound exciting? 
Here is the [live link](https://scrollmovies.netlify.app/) and [source code.](https://github.com/jorjishasan/Movie-Pedia)

**Visual Picture:** 


![a screenshot from app](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/abounmbzv3o4j8erwtwh.jpeg)


---
**Step 1:** 

First, we need to make a basic utility movie card. After that we'll add features to that component.


```js
//MovieCard.js

import { mediaUrl } from "./constants";

const MovieCard = ({ info }) => {
  const { id, backdrop_path, original_title } = info;

  return (
    <div className="rounded-lg overflow-hidden drop-shadow-md max-w-[400px] border-[1px] border-gray-400">
      <img key={id} src={mediaUrl + backdrop_path} />
      <div className="bg-w font-sans py-4 text-center font-semibold font-xl">
        {original_title}
      </div>
    </div>
  );
};

export default MovieCard;
```
This code block will render the core `MovieCard` with essential movie data like `movie poster` and `title`.

![Movie Card](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/b6u36gahfbdv6esfbhps.jpeg)

**Step 2:** 
Now, without touching/modifying the core `MovieCard` code, let's create a version of MovieCard by adding the `New` label.

```js
// WithNewLabel (higher-order-component)
export const WithNewLabel = (MovieCard) => {
  return (props) => {
    return (
      <div>
        <label className="absolute z-10 bg-blue-600 text-white rounded-lg py-2 px-4">
          New 🌱
        </label>
        <MovieCard {...props} />
      </div>
    );
  };
};
```

The new enhanced version of the movie card component will look like this.

![solo screenshot](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8tmixe8tih24hk0dwrqx.jpeg)

For the sake of a higher-order component, it's easy to add/remove variable features like 'popular,' 'new,' or 'trending', anything that fits our needs. 

**Rendering On Condition:**

We are done making components `MovieCard` and `WithNewLabel` as higher-order components. It's time to see the use cases in action.

```js
import React from "react";
import ReactDOM from "react-dom/client";
import MovieCard, { WithNewLabel } from "./MovieCard";

const movieList = [
  {
    backdrop_path: "/6Xfj8wD7GoEysgcFayRKd6QLqai.jpg",
    id: 843527,
    original_title: "The Idea of You",
    release_year: 2024,
    release_month: 5,
  },
  {
    backdrop_path: "/nb3xI8XI3w4pMVZ38VijbsyBqP4.jpg",
    id: 872585,
    original_title: "Oppenheimer",
    release_year: 2023,
    release_month: 7,
  },
];

const isNewMovie = ({ release_year, release_month }) => {
  return release_year === 2024 && release_month > 2 ? true : false;
};

const Body = () => {
  <div className="flex flex-wrap flex-row gap-[16px] justify-evenly">
    {movieList.map((movie) => {
      const NewLabel = WithNewLabel(MovieCard);

      if (isNewMovie(movie)) {
        return <NewLabel key={movie.id} info={movie} />;
      } else {
        return <MovieCard key={movie.id} info={movie} />;
      }
    })}
  </div>;
};

const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(<Body />);
```

The code written above will visually look like this:

![Visual Illustration](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/q9nn7hjernsklko1x4j6.jpeg)