What are higher order components in React?
TL;DR
Higher order components (HOCs) in React are functions that take a component and return a new component with additional props or behavior. They are used to reuse component logic. For example, if you have a component MyComponent, you can create an HOC like this:
const withExtraProps = (WrappedComponent) => {return (props) => <WrappedComponent {...props} extraProp="value" />;};const EnhancedComponent = withExtraProps(MyComponent);
HOCs are largely a legacy pattern. The current React docs (React 19) discourage HOCs in favor of custom hooks for sharing logic between function components. You'll still see HOCs in older code and in libraries (e.g. connect from React Redux), but for new code, prefer hooks.
What are higher order components in React?
Definition
Higher order components (HOCs) are functions in React that take a component as an argument and return a new component. The new component typically wraps the original component and adds additional props, state, or behavior. HOCs are a pattern for reusing component logic.
As of React 19, the official documentation discourages HOCs for new code and recommends custom hooks instead. HOCs remain mostly relevant for compatibility with older codebases and libraries.
Purpose
HOCs are used to:
- Share common functionality between components
- Abstract and reuse component logic
- Enhance components with additional props or state
Example
Here is a simple example of an HOC that adds an extraProp to a wrapped component:
import React from 'react';// Define the HOCconst withExtraProps = (WrappedComponent) => {const ComponentWithExtraProps = (props) => {return <WrappedComponent {...props} extraProp="value" />;};// Set a useful displayName for debugging in React DevToolsconst wrappedName =WrappedComponent.displayName || WrappedComponent.name || 'Component';ComponentWithExtraProps.displayName = `withExtraProps(${wrappedName})`;return ComponentWithExtraProps;};// Define a component to be wrappedconst MyComponent = (props) => {return <div>{props.extraProp}</div>;};// Wrap the component using the HOCconst EnhancedComponent = withExtraProps(MyComponent);// Use the enhanced componentconst App = () => {return <EnhancedComponent />;};export default App;
In this example, withExtraProps is an HOC that adds an extraProp to MyComponent. The EnhancedComponent now has access to extraProp. The displayName convention withExtraProps(MyComponent) makes the component identifiable in React DevTools.
Common use cases
- Authentication: Wrapping components to check if a user is authenticated before rendering.
- Logging: Adding logging functionality to components.
- Theming: Injecting theme-related props into components.
- Data fetching: Fetching data and passing it as props to components.
Best practices
- Do not mutate the original component: Always return a new component.
- Do not create HOCs inside the render method: Calling
withExtraProps(MyComponent)inside another component's render produces a brand-new component type on every render, so React unmounts and remounts the subtree, losing all state and DOM. Apply HOCs at the module level. - Set a
displayName: Wrap the inner name asHOCName(WrappedName)so React DevTools shows something useful instead ofAnonymous. - Watch for prop-name collisions: An HOC that injects, say, an
extraPropwill silently overwrite anyextraPropthe caller passes in (or vice versa, depending on spread order). Namespace injected props or document them clearly. - Forward refs explicitly: Wrapping a component in an HOC means a
refpassed by the consumer lands on the wrapper, not the inner component. In React 19,forwardRefis deprecated andrefis now a regular prop on function components, so the simplest fix is to acceptrefas a prop and forward it:<WrappedComponent {...props} ref={props.ref} extraProp="value" />. For pre-19 codebases, you'd useReact.forwardRefinside the HOC. - Use HOCs sparingly: Overusing HOCs can make the code harder to understand and creates deeply nested wrapper trees ("wrapper hell"). Custom hooks usually compose more cleanly.
Alternatives
- Custom hooks (preferred for new code): Custom hooks can share stateful logic between function components without adding extra wrapper components to the tree. This is the React 19 recommendation.
- Render props: A pattern where a component uses a function as a prop to determine what to render.