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.