What are Higer order components
Aside from the name sounding like it came from star wars. A higher-order component (HOC) is an advanced technique in React for reusing component logic, and computed state.
It solves the problem of accessing logic, and computed states that lives in a separate component without rewriting, refetching, or lifting them up. HOCs solve it by pre-processsing and modifying the props before sending them to the consuming component.
HOCs are comparable to dependency injections
- They are not a part of the view system.
- Computes, and modifies state before sending it to a consuming component.
If a component requested for a data. Our HOC can cache that data to avoid refetching it in every instance of our HOC.
Example problem
Let's say we need to display the user's fullName(computed firstName + lastName) in both the Navbar
and MainContent
components. But we fetched the user
data within the Navbar
component.
How are we going to access that data on our MainContent
component?
There are 3 ways this can be solved:
- Refetch the
user
data, and recompute the user's fullName in the MainContent component. ❌ - Lift the state up. Well... This is an HOC article so we're not doing this.
- Create an HOC to compute, and fetch data then consume it on our components. ✅
export const Navbar = ({ name, color }) => {
return <div>{name}</div>
}
export const MainContent = ({ name }) => {
return <div>Hello {name}</div>
}
export const withName = (Component) => (props) => {
const user = {
firstName: 'Roman',
lastName: 'Munar'
}
const userFullName = `${user.firstName} ${user.lastName}`
return <Component {...props} name={userFullName} />
}
export const MainContentWithName = withName(MainContent)
export const NavbarWithName = withName(Navbar)
// Later on...
// No need to pass a name prop
<NavbarWithName color='#000' />
// Can still be used with custom name prop
<Navbar name='Sup' color='#000' />
Caveats
Using HOCs with Typescript can be challenging because we are applying some props on our own, and some passed unto the component. So avoid using components with and without HOCs If you're using Typescript.
Conclusion
Useful for cross cutting logic, and computed states. at some point though you might want to use atoms. As you'll soon face computed states from other HOCs that would warrant you to wrap an HOC with another HOC which is hard to read, and change.
If you liked this article I'm sure you'll like the article I wrote about the renderProps Pattern even more.