November 22, 2025
Higher-Order Components (HOCs) were once one of the most popular techniques to reuse logic in React. Although custom hooks are now the preferred option, HOCs remain useful in specific situations such as cross-cutting concerns, prop injection, conditional wrappers, feature flags, logging, tracking, and access control.
A Higher-Order Component is a function that takes a component and returns a new component with extended functionality:
1function withSomething<P>(Component: React.ComponentType<P>): React.FC<P> {
2 return function WrappedComponent(props: P) {
3 return <Component {...props} />;
4 };
5}
6
HOCs remain valuable for cross-cutting concerns, component decoration, and prop injection.
1import React from "react";
2
3type Permission = "read" | "write" | "admin";
4
5interface WithPermissionProps {
6 userPermissions: Permission[];
7}
8
9export function withPermission<P extends object>(
10 required: Permission,
11 Component: React.ComponentType<P>
12): React.FC<P & WithPermissionProps> {
13 return function WithPermissionComponent(props) {
14 const { userPermissions, ...restProps } = props;
15
16 const isAllowed = userPermissions.includes(required);
17
18 if (!isAllowed) {
19 return <div>You do not have permission to view this content.</div>;
20 }
21
22 return <Component {...(restProps as P)} />;
23 };
24}
25
Use
1P extends object1React.ComponentType<P>1import React from "react";
2import { useQuery } from "@apollo/client";
3
4export function withUser<P extends object>(
5 Component: React.ComponentType<P & { user: any }>
6): React.FC<P> {
7 return function WithUser(props) {
8 const { data, loading } = useQuery(GET_ME);
9
10 if (loading) return <p>Loading...</p>;
11
12 return <Component {...props} user={data.me} />;
13 };
14}
15
HOCs remain powerful in modern React applications using TypeScript, especially when applying clean code principles.