React Course
React
/
Advanced

HOCs & Render Props

Definition

Higher-Order Components (HOCs) and Render Props are two advanced React patterns used to share logic between components. An HOC is a function that takes a component and returns a new component. A Render Prop is a technique for sharing code using a prop whose value is a function.

Explain Like I'm New

Imagine you have a 'Hover Detector' logic. Instead of copying that code into 10 different buttons and images, you can use these patterns. An HOC is like a jacket you put on your component: `withHover(Button)`. A Render Prop is like handing the component a remote control: `<HoverDetector render={(isHovered) => <Button active={isHovered} />} />`.

Real World Example

Before Hooks, Redux's `connect()` was the most famous HOC. React Router used Render Props extensively. Today, Custom Hooks have mostly replaced both of these patterns, but they are highly common in legacy codebases and still asked in senior interviews.

Common Use Cases

  • Reusing cross-cutting concerns (like analytics tracking or authentication checks)
  • Injecting extra props into a component
  • Maintaining legacy React codebases built before Hooks (React 16.8)

Interactive Example

import React, { useState } from 'react';

// --- 1. The Render Props Pattern ---
// It handles the state, and 'renders' whatever you pass it
const MouseTracker = ({ renderCallback }) => {
  const [position, setPosition] = useState({ x: 0, y: 0 });

  const handleMouseMove = (e) => setPosition({ x: e.clientX, y: e.clientY });

  return (
    <div style={{ height: '100px', background: '#eee' }} onMouseMove={handleMouseMove}>
      {/* We call the prop as a function, passing the state to it */}
      {renderCallback(position)}
    </div>
  );
};

export default function App() {
  return (
    <div>
      <h2>Render Props Example:</h2>
      <MouseTracker 
        renderCallback={(mouse) => (
          <p>The mouse is at X: {mouse.x}, Y: {mouse.y}</p>
        )}
      />
    </div>
  );
}

// --- 2. The HOC Pattern (For Reference) ---
// const withMouse = (WrappedComponent) => {
//   return (props) => {
//     const [pos, setPos] = useState({x: 0, y: 0});
//     return <WrappedComponent {...props} mouse={pos} />
//   }
// }

Interview Questions

basic

  • What is a Higher-Order Component (HOC)?
  • What is a Render Prop?

intermediate

  • Why did Custom Hooks largely replace HOCs and Render Props?
  • What is the 'Wrapper Hell' problem?

advanced

  • How do you pass refs through an HOC? (Hint: React.forwardRef)
  • Why shouldn't you define an HOC inside the render method of another component?

trick

  • Does a Render Prop literally have to be named 'render'?

Flash Cards

Question

Why did Custom Hooks replace them?

Click to reveal answer
Answer

HOCs and Render Props cause 'Wrapper Hell'—deeply nested DOM trees of wrapper components just to share logic. Custom Hooks allow you to extract stateful logic into a simple function call without altering the component tree.

Question

Why shouldn't you define an HOC inside a render method?

Click to reveal answer
Answer

If you dynamically create an HOC inside a render method, React sees it as a brand new component on every render. It will unmount the old one and mount the new one entirely, destroying all state and DOM nodes.

Question

Does a Render Prop literally have to be named 'render'?

Click to reveal answer
Answer

No! It can be named anything. In fact, using the `children` prop as a function is one of the most common ways to implement the Render Props pattern.