Logo

dev-resources.site

for different kinds of informations.

React - Higher Order Components (HOC)

Published at
8/15/2023
Categories
react
hoc
beginners
component
Author
brdnicolas
Categories
4 categories in total
react
open
hoc
open
beginners
open
component
open
Author
10 person written this
brdnicolas
open
React - Higher Order Components (HOC)

In the ever-evolving realm of web development, mastering advanced concepts is essential for creating robust and flexible applications. In this article, we'll delve into one of these foundational React concepts: Higher-Order Components, commonly known as HOCs. 

Whether you're a seasoned developer seeking advanced techniques or a curious beginner eager to learn, we'll walk through the creation and application of HOCs step by step. Get ready to enrich your development toolkit with this powerful approach while discovering how to enhance the readability, reusability, and maintainability of your code.


What is a Higher Order Component?

Imagine that you own a pastry shop and you specialize in creating a wide variety of pastries. In your pastry shop, you have croissants, muffins, and danishes. Each pastry must have a label indicating its type and ingredients. If you were to do this for every pastry manually, it would require a significant amount of time. Instead of doing it manually, you can use a "robot" that will do it automatically for you.

This robot is a Higher-Order Component (HOC), a function that takes a component (your pastry) and returns your pastry with additional functionalities or features (in this case, a label indicating its type and ingredients).


Advantages

Higher-Order Components (HOCs) offer several significant advantages that enhance how we develop our React applications. Here are some of these advantages, accompanied by concrete examples:

  • Reusability: One major strength of HOCs is their ability to be reused in different parts of your application. Since an HOC is a function with specific logic, you can customize it to suit your needs while keeping it flexible. For instance, an authentication HOC could be adapted to handle access to different types of content. 
  • Separation of Concerns: Instead of cluttering a component with multiple distinct logics, HOCs allow for the separation of these responsibilities into distinct components. You can easily envision creating a separate HOC for each logic, making your components clearer and better organized. 
  • Code Modularity: HOCs add a modular layer to your code. You can add or remove an HOC without affecting the functionality of the underlying component, making maintenance and adaptation of your application easier. In essence, HOCs nest without altering overall stability. 
  • Facilitation of Unit Testing: Due to their isolated nature, HOCs simplify unit testing. You can test the specific logic of an HOC without the complexity of other parts of the application.

By combining these advantages, you'll be able to create more flexible and maintainable applications while minimizing code duplication.


Practical Case

The problem

Let's take a concrete example to illustrate the relevance of Higher-Order Components. Suppose we're developing an application with an authentication system. In this application, different parts of the interface require authentication:

  • Home Page: This page doesn't require authentication.
  • List of Books: This list can be viewed without authentication.
  • Top Books: This section is reserved for authenticated users.
  • User Ratings: Similarly, only logged-in users can view the ratings.

Imagine we have a component that imports all the others:

export const App = () => {
  return (
    <div>
      <Home />
      <BooksList />
      <TopBook />
      <UsersRating />
    </div>
  )
}
Enter fullscreen mode Exit fullscreen mode

Now, let's consider a component for each part:

export const Home = () => {
  return (
    <div>
      <h1>Hey !</h1>
      <p>This is a welcome message !</p>
    </div>
  )
}
Enter fullscreen mode Exit fullscreen mode
export const BooksList = () => {
  return (
    <div>
      <p>Books list</p>
    </div>
  )
}
Enter fullscreen mode Exit fullscreen mode
export const TopBook = () => {
  const isConnected = false

  if(!isConnected) {
    return (
      <p>You don't have access !</p>
    )
  }

  return (
    <div>
      <p>Top Book</p>
    </div>
  )
}
Enter fullscreen mode Exit fullscreen mode
export const UsersRating = () => {
  const isConnected = false

  if(!isConnected) {
    return (
      <p>You don't have access !</p>
    )
  }

  return (
    <div>
      <p>UsersRating</p>
    </div>
  )
}
Enter fullscreen mode Exit fullscreen mode

We notice that the two components with the restriction logic repeat the same code. While this isn't a big issue with only two components, imagine having 10 components - that's a lot of code repetition. Given this scenario, it's important to find a solution that handles conditional content display based on authentication status.

This is where Higher-Order Components (HOCs) come into play.

Solution : Higher Order Components (HOCs)

To address this issue of code repetition in multiple places, let's isolate the authentication logic in an HOC called withAuthentication:

export const withAuthentication = (Component) => {
  const isConnected = false

  if (!isConnected) {
    return <p>You don't have access !</p>
  }

  return (props) => <Component {...props} />
}
Enter fullscreen mode Exit fullscreen mode

Next, we'll apply this HOC to the components that require access restriction, like this:

export const TopBook = withAuthentication(() => {
  return (
    <div>
      <p>Top Book</p>
    </div>
  )
})
Enter fullscreen mode Exit fullscreen mode
export const UsersRating = withAuthentication(() => {
  return (
    <div>
      <p>UsersRating</p>
    </div>
  )
})
Enter fullscreen mode Exit fullscreen mode

Assuming you retrieve isConnected from either props or context, you now have isolated and reusable logic.


Going further

We can go further with HOCs. Let's imagine now that we want to do some layout work with a profile view:

export const Profile = () => {
  // This is the beta version of the Profile

  return (
    <div>
      <p>Beta Profile</p>
      <h1>Nicolas BROUARD</h1>
    </div>
  )
}
Enter fullscreen mode Exit fullscreen mode

We have our Profile view and we want to add a "Beta" banner to indicate that this is indeed the Beta version of the profile. We can also use an HOC:

export const withBetaBanner = (Component) => {
  return (props) => (
    <>
      <header className="beta-header">This is a beta version</header>
      <Component {...props} />
    </>
  )
}
Enter fullscreen mode Exit fullscreen mode

You can easily nest various HOCs if needed:

const ProtectedBetaProfile = withAuthentication(withBetaBanner(Profile))

return <ProtectedBetaProfile />;
Enter fullscreen mode Exit fullscreen mode

This allows you to isolate different rules, making unit testing easier! You can also manipulate props if necessary. HOCs are very powerful!


You can also manipulate props if necessary. HOCs are very powerful!

Conclusion

In conclusion, you now have all the tools you need to fully leverage the power of Higher-Order Components (HOCs) in your React projects.

By combining concepts such as prop forwarding, HOC composition, and using TypeScript for type safety, you can create more flexible, cleaner, and efficient components. HOCs provide a practical approach to handling cross-cutting concerns and simplifying your components, which can greatly facilitate maintenance and expansion of your applications. Keep experimenting with HOCs in your projects and don't hesitate to explore concrete examples to deepen your understanding.

Mastering the art of HOCs will give you a significant advantage in building robust and scalable React applications. So, dive in, apply this knowledge, and transform your components into flexible and powerful building blocks for your future React creations.

If you enjoyed this tutorial, please consider following me for more helpful content. Your support is greatly appreciated! Thank you!

component Article's
30 articles in total
Favicon
Build a note app with JavaScript component.
Favicon
Key characteristic of Component-Based Architecture
Favicon
React Component Libraries: Overview of 19 Top Libs
Favicon
Styling Components in React 🧢
Favicon
Building a Seamless OTP Input Field in React: A Step-by-Step Guide
Favicon
MithrilJS component with state management
Favicon
[Off Topic] Nano introdução do framework Angular para Devs do back
Favicon
Comparing Vue Component Documentation tools
Favicon
Laravel 11 Custom Component File Structure
Favicon
Building Message Component in Vue3
Favicon
Aplicando paginação em um componente Select
Favicon
How much does it cost to repair an outdoor LED display?
Favicon
Global toast in Vue3
Favicon
Unveiling the Hidden Gem of React: The Power of Compound Components
Favicon
Controlled vs Uncontrolled Components in React
Favicon
React components -(Class component v/s function component)
Favicon
3 Ways to Create React Components with Bit
Favicon
Client or Server component ?
Favicon
Desenvolvimento de Componentes AssĂ­ncronos com Vue.js
Favicon
NAND Flash vs NOR Flash: Differences between them
Favicon
Link Component in React Router
Favicon
Guia de Components - para quem tem pressa!
Favicon
How to exchange data between Angular components
Favicon
Component Testing with Cypress and Reactjs
Favicon
React - Higher Order Components (HOC)
Favicon
How to Create Component Library Like Material UI or Mantine UI?
Favicon
Looking forward to adding Algolia's DOCSEARCH to Mantine DataTable
Favicon
Cypress Component Testing vs React Testing Library - the complete comparison
Favicon
Creating Custom Component for NPS Feedback
Favicon
Maximize your Angular code reusability using <NgTemplateOutlet>

Featured ones: