Higher-Order Components (HOC) in React

November 18, 2019

A higher-order component in react is a function that takes a component and returns a new component.

const EnhancedComponent = hoc(WrappedComponent);

Let’s start with a simple example named withUser. The purpose for withUser it to wrap around any component I pass to it and provide our user context as a prop. If you don’t know about React context, it is the way how I pass the current authenticated user to the components. So my component will be able to display information for authenticated user.

Const withUser = Component => {
Const WrappedComponent = props => (
<UserContext.Consumer>
{user => <Component user = {user} {...props} />}
</UserContext.Consumer>
);
Return WrappedComponent
};

By using withUser function, it will be able to return any component with the current authenticated user provided. This is the enhanced component.

Const UserProfilePage = props => (
<section className = “userProfile”>
<p>Hello, {props.user}! </p>
</section>
);
Export default withUser(UserProfilePage);

Pros of HOCs:

  • Keep code DRY (Don’t Repeat Yourself).
  • Separations of concern. Easily separate all logic from the UI component.
  • Keep functional components pure.
  • Easy to compose. The compose function from ‘recompose’ allows multiple HOCs to be composed into one.
  • GOOD when it can apply to many components in the app.
  • GOOD when it doesn’t need to provide a bunch of props.
  • GOOD when no custom logic needs to be added to the wrapped component.

Cons of HOCs:

  • It may cause problems when we have many HOCs since every change in the parent props caused the children to re-render.
  • It is difficult to know which props and types we are getting, but that’s why it is easy for us to use.
  • BAD when it requires a bunch of props to the component since it will just pass all the props to the child even if the child only needs one.
  • BAD when it only applies to one or few components.
  • BAD when the wrapped components need to be customized.
  • It can be complicated to debug especially when it required using an argument that depends on a component’s props.