DEV Community

Cover image for Utilizing Higher-Order Components (HOC) and Function Composition to Enhance React Code Structure
Alexey Lysenko
Alexey Lysenko

Posted on

Utilizing Higher-Order Components (HOC) and Function Composition to Enhance React Code Structure

In the world of React development, the need often arises to enforce access restrictions on various app modules. Let's delve into an approach leveraging Higher-Order Components and Function Composition to tackle this challenge effectively.

Consider the scenario where we aim to ascertain if a user is logged in before rendering certain components. We initially might resort to a straightforward implementation:

 function Account() {
  const sessionContext = useSessionContext();

   if (!sessionContext.isAuthenticated) {
      return <RedirectTo href={PATH_LOGIN} />;
    }

  return (
    <SomeAccountData />
  );
};
Enter fullscreen mode Exit fullscreen mode

However, such an approach presents drawbacks:

  1. The necessity to import useSessionContext within the Account component, entangling business logic with presentation.
  2. Repetition of authentication logic across multiple modules leads to code duplication and maintenance challenges.

Higher-Order Components

To solve these issues, we can use Higher-Order Components. Let's craft a function withAuthenticatedUser to encapsulate authentication logic:

function withAuthenticatedUser<T>(WrappedComponent: React.ComponentType<T>) {
  function WithAuthenticatedUser(props: React.PropsWithChildren<any>) {
    const sessionContext = useSessionContext();

    if (!sessionContext.isAuthenticated) {
      return <RedirectTo href={PATH_LOGIN} />;
    }

    return <WrappedComponent {...props} />;
  }

  return WithAuthenticatedUser;
}

// Apply the HOC to our Account component
const WrappedAccount = withAuthenticatedUser(Account);

Enter fullscreen mode Exit fullscreen mode

This cleaner approach enables seamless reuse of the authentication wrapper across various components.

Function Composition for combining a lot of HOCs.

Function Composition further enhances our code organization by consolidating multiple HOCs into a single entity. Let's explore this concept.

By leveraging Function Composition, we efficiently combine various HOCs to create a cohesive single HOC wrapper around our components.

export const compose =
  (...funcs) =>
  (Component) =>
    funcs.reduce((wrappedComponent, hoc) => 
    hoc(wrappedComponent), Component);

// Combine multiple wrappers using function composition
const Account = compose(
  withAuthenticatedUser,
  withFeatureFlag,
  withLogger,
)(function Account() {
  return (
    <SomeAccountData />
  );
});

Enter fullscreen mode Exit fullscreen mode

In summary, when faced with the need for consistent actions across multiple components, consider harnessing Higher-Order Components and Function Composition as powerful tools for enhancing code maintainability and scalability in your React applications.

Top comments (0)