HOCs at a glance

Reusing component code and logic is one of the things developers are looking for the most, specially in React. The very concept of Components applies for this. A higher-order component (HOC) is an advanced technique for reusing component logic in React.

Concretely, a higher-order component is a function that takes a component and returns another component

const EnhancedComponent = highOrderComponent(WrappedComponent)

HOCs are very common in third part React libraries, such as Redux.

In this post, we will learn how to use this technique and how to write your own higher-order components

The implementation of a higher-order component usually looks like this

const HighOrderComponent = (WrappedComponent, props) => {
const injectedProp = someInstanceOrMethod()

return (
<WrappedComponent injectedProp={injectedProp} {...props} />
)
}

Now, let’s see a real usage of this. For example, say you have a private page in your app that only logged users can access.

The isLogged logic looks like this

const isLogged = () => {
const user = localStorage.getItem('myUser')
return !!user
}

Without using hocs, you would need to repeat the validation logic for every new private page you add in your app

const MyPage = () => {
if(!isLogged()) {
// SHOW ALERT MESSAGE OR REDIRECT USER TO A PUBLIC PAGE
} else {
return <h1>My component</h1>
}
}

Or even worse, if we need to add another type of validation after the isLogged call, like an API call to validate the user token, or ask some information to the user, we will need to change every file where the isLogged function is being called.

There are a few strategies to handle this issue, a HOC is one of them

Our higher-order component

export const withPrivate = Component => {
if (isLogged()) return <Component />

return <h1>You are not logged!</h1>
}

Now, our private page is only responsible for their own methods and logic, independent of the application auth logic

const MyPage = () => {
return <h1>My Component</h1>
}

// Use the withPrivate HOC to export the component
export default withPrivate(MyPage)

And the best part, if we need to do any changes on the isLogged method, or add another validation after that, we will make this directly into the withPrivate method, without modifying anything in the component code

export const withPrivate = Component => {
if (isLogged()) {
const user = AuthService.getUser()
const userToken = AuthService.getToken(user.email)

if (userToken) return <Component />
}

return <h1>You are not logged!</h1>
}

And that’s it, we just added another validation to our withPrivate HOC, and our private route doesn’t even know it is different!

Find this useful? Follow me on social media

https://github.com/giovaniif

https://www.linkedin.com/in/giovani-farias-b97316186/

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store