Higher-Order Components (HOC) is a quite common pattern in React. It’s heavily related to the higher-order functions in plain JS. To start our discussion of the first topic we first need to build a solid understanding of the second one.
First-order functions
When a function is using only primitive types as arguments or return values we tend to call it to be a first-order function.
const sum = (a, b) => {
return a + b
}
The above sum function is quite straightforward. It accepts two primitive type arguments and returns their sum.
Higher-order functions
On the other hand, if a function either takes another function as an argument or returns one then we call it higher-order. We don’t have to look really far for examples.
const arr = [1,1,2,3,5,8]
const doubledArr = arr.map((n) => n * 2)
As you can see in the above example the higher-order function map takes in another function as an argument.
Higher-order components
HOC are functions that take components as arguments and return components. It’s a common practice used with some advanced React pattern. You may have used the connect function that’s used with Redux, it’s nothing else that a HOC.
Let’s start by writing our higherOrderComponent function. This function will take the component as an argument and inject the global state to it’s props. In our simple case we’ll use the mock user data.
const higherOrderComponent = ProcessedComponent => {
const user = {
name: 'Tommy',
surname: 'Smith'
}
return class HOC extends React.Component {
render() {
return <ProcessedComponent name={user.name} surname={user.surname}/>
}
}
}
Let’s start by writing our higherOrderComponent function. This function will take the component as an argument and inject the global state to it’s props. In our simple case we’ll use the mock user data.
Firstly we define the mock state in the body of the function. We’re then moving straight on to returning a new component from it. That component only implements the render function in which it returns the ProcessedComponent argument and injects it the user data.
import React from 'react'
const User = ({ name, surname }) => {
return (
<div>
<h1>Current User:</h1>
<h2>{name} {surname}</h2>
</div>
)
}
export default higherOrderComponent(User)
In User.js we’ve defined the User component. This component simply returns the user’s name and surname in and h2 element. In the export statement we’re calling the higherOrderComponent with the User component as an argument.
We can then simply import the component in the desired use place and enjoy the benefits!
import User from './User'
function App() {
return (
<div style={{ margin: '50px' }}>
<User />
</div>
);
}
export default App;
And now if you take a look at what the application renders to the page, you can see that it successfully injected the data.
💬 Leave a comment