November 22, 2025

Higher-Order Components, A Clean Code Approach

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.

1. What Is a Higher-Order Component?

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

2. When Should You Use HOCs in 2025?

HOCs remain valuable for cross-cutting concerns, component decoration, and prop injection.

3. Practical Example: Permission-Based HOC (RBAC)

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

4. Typing HOCs Correctly in TypeScript

Use

1P extends object
,
1React.ComponentType<P>
, and extended prop types.

5. Clean Code & Best Practices for HOCs

  • Single Responsibility Principle\
  • Keep HOCs pure\
  • Use descriptive names\
  • Preserve displayName\
  • Never mutate props\
  • Avoid altering original component behavior

6. Modern HOC Using Hooks

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

Conclusion

HOCs remain powerful in modern React applications using TypeScript, especially when applying clean code principles.