Component Patternsmedium

Higher-Order Components (HOC)

A higher-order component is a function that takes a component and returns a new component with enhanced behavior. It's the React equivalent of a decorator pattern: withAuth(Dashboard) returns an AuthenticatedDashboard.

Memory anchor

An HOC is a phone case — it wraps around your phone (component), adds features (grip, card holder), but the phone inside works the same. Stack too many cases and it gets unwieldy.

Expected depth

HOCs wrap a component, injecting props from shared logic. Examples: withRouter (React Router v5), connect (Redux), withTheme. HOCs should pass through all received props to the wrapped component and hoist static methods using hoist-non-react-statics. They compose well: compose(withAuth, withTheme, withRouter)(MyComponent). The drawback is 'wrapper hell' in DevTools and potential prop name collisions.

Deep — senior internals

HOCs are largely replaced by hooks in modern React, but understanding them is important for legacy codebases and for the pattern itself. Key rules: don't mutate the original component (create a new one), forward refs with React.forwardRef, and copy over displayName for debugging. HOCs break if applied inside render (creates new component type each render, causing remount). Always apply HOCs outside the component definition. TypeScript generic HOCs are notoriously hard to type correctly.

🎤Interview-ready answer

HOCs are functions that wrap a component to inject additional behavior via props. They were the go-to pattern before hooks for cross-cutting concerns like auth, theming, and routing. I still encounter them in legacy codebases and Redux's connect. For new code, I prefer hooks because they avoid wrapper hell, prop collisions, and the DevTools debugging challenges of deeply nested HOCs.

Common trap

Applying an HOC inside a render method creates a new component type on every render, causing the entire subtree to unmount and remount. Always apply HOCs at the module level.

Related concepts