Higher‑Order Components: The Legacy Pattern You'll Still Meet
Wrap a component to inject extra props. Useful to understand, even if hooks are preferred today.
Introduction
A Higher‑Order Component (HOC) is a function that takes a component and returns a new one with extra behavior or props. Even though hooks are preferred today, HOCs still appear in older codebases and some libraries.
Why this matters
A Higher‑Order Component (HOC) is a function that takes a component and returns a new component with added behavior or props. While hooks replaced most HOCs, you’ll still see them in older codebases and some libraries.
The problem
We want to provide a user prop to a component without threading it through every usage.
Inefficient approach
Manually passing user everywhere makes usage noisy:
function UserProfile({ user }) {
return (
<div>
<h2>{user.name}</h2>
<p>{user.email}</p>
</div>
);
}
function App() {
const user = { name: "John Doe", email: "john@example.com" };
return (
<div>
<h1>Higher-Order Components</h1>
<UserProfile user={user} />
</div>
);
}
export default App;
The solution
Write a withUser HOC that returns an enhanced component.
function withUser(Component) {
const user = { name: "John Doe", email: "john@example.com" };
return function EnhancedComponent(props) {
return <Component {...props} user={user} />;
};
}
function UserProfile({ user }) {
return (
<div>
<h2>{user.name}</h2>
<p>{user.email}</p>
</div>
);
}
const EnhancedUserProfile = withUser(UserProfile);
function App() {
return (
<div>
<h1>Higher-Order Components</h1>
<EnhancedUserProfile />
</div>
);
}
export default App;
Knowledge base
Problem snippet:
function App() {
const user = { name: "John Doe", email: "john@example.com" };
return <UserProfile user={user} />;
}
Solution snippet:
const EnhancedUserProfile = withUser(UserProfile);
<EnhancedUserProfile />
Tips
- Name HOCs by behavior:
withAuth,withFeatureFlags, etc. - Preserve static properties if needed (many libraries provide helpers).
- Prefer hooks for new code; reach for HOCs mainly when interop requires it.