HOC vs Render Props in React: Key Differences and Usage
Higher-Order Component (HOC) is a function that takes a component and returns a new enhanced component, while Render Props is a technique where a component accepts a function as a prop to control what to render. Both share logic but differ in syntax and flexibility.Quick Comparison
Here is a quick side-by-side comparison of HOC and Render Props in React.
| Factor | Higher-Order Component (HOC) | Render Props |
|---|---|---|
| Definition | Function that returns a new component wrapping the original | Component that takes a function prop to render content |
| Syntax | Wraps component with another component | Passes a function as a prop to control rendering |
| Usage | Enhances component behavior by wrapping | Shares code by calling a function to render UI |
| Flexibility | Less flexible, fixed wrapping structure | More flexible, can render anything inside function |
| Readability | Can cause nested wrappers (wrapper hell) | Can cause nested functions but clearer intent |
| Props Handling | Passes props automatically to wrapped component | Function receives data and returns UI explicitly |
Key Differences
Higher-Order Components (HOCs) are functions that take a component and return a new component with added features. They wrap the original component, injecting props or behavior. This pattern is useful for reusing logic like data fetching or theming but can lead to deeply nested wrappers, making debugging harder.
Render Props use a different approach: a component accepts a function as a prop and calls it to decide what to render. This gives more control over rendering and can be more flexible for complex UI needs. It avoids some nesting issues but can introduce nested functions that might look complex.
While both patterns share logic between components, HOCs focus on wrapping and enhancing components, whereas Render Props focus on sharing rendering logic through functions. Choosing between them depends on the use case and code clarity preferences.
Code Comparison
This example shows a simple counter logic shared using a Higher-Order Component.
import React, { useState } from 'react'; function withCounter(WrappedComponent) { return function WithCounter(props) { const [count, setCount] = useState(0); const increment = () => setCount(count + 1); return <WrappedComponent count={count} increment={increment} {...props} />; }; } function ClickCounter({ count, increment }) { return <button onClick={increment}>Clicked {count} times</button>; } const EnhancedClickCounter = withCounter(ClickCounter); export default function App() { return <EnhancedClickCounter />; }
Render Props Equivalent
The same counter logic implemented using Render Props pattern.
import React, { useState } from 'react'; function Counter({ children }) { const [count, setCount] = useState(0); const increment = () => setCount(count + 1); return children(count, increment); } function App() { return ( <Counter> {(count, increment) => ( <button onClick={increment}>Clicked {count} times</button> )} </Counter> ); } export default App;
When to Use Which
Choose Higher-Order Components (HOCs) when you want to enhance or wrap components with additional behavior in a reusable way, especially if you want to keep your component usage simple and declarative.
Choose Render Props when you need more control over what gets rendered and want to share complex UI logic that varies between uses. Render Props offer more flexibility for dynamic rendering but can be more verbose.
In modern React, hooks often replace both patterns, but understanding these helps maintain and read older codebases.