📘 ReactJS

Render Props & Compound Components

Render Props and Compound Components are two important React composition patterns. Render Props focus on sharing behavior by allowing the consumer to provide a rendering function. Compound Components focus on creating a group of components that work together through shared state and context.

S

Site Administrator

📅 Sep 28, 2026 🕒 4 min read 👁 23 views
☆ Save 𝕏 in f ✆
Render Props & Compound Components

Render Props and Compound Components are two important React composition patterns. Render Props focus on sharing behavior by allowing the consumer to provide a rendering function. Compound Components focus on creating a group of components that work together through shared state and context.

What is the Render Props pattern?

A Render Prop is a function passed to a component that the component calls to decide what UI to render. The function can receive data or behavior from the parent component.

function MouseTracker({ render }) {
  const [position, setPosition] = useState({ x: 0, y: 0 });

  return render(position);
}

function App() {
  return (
    <MouseTracker
      render={position => (
        <p>
          X: {position.x}, Y: {position.y}
        </p>
      )}
    />
  );
}

Render Props flow

flowchart TD
A[Consumer provides render function] --> B[Reusable component]
B --> C[Owns behavior or state]
C --> D[Calls render function]
D --> E[Consumer controls UI]

Why Render Props were useful

The pattern separated reusable behavior from presentation. A component could manage subscriptions, mouse position, data loading, or other state while the consumer decided exactly how the information should be displayed.

Children as a function

A common variation uses the children prop as a function.

function DataProvider({ children }) {
  const data = { name: "Product", price: 100 };

  return children(data);
}

function App() {
  return (
    <DataProvider>
      {data => <p>{data.name}: {data.price}</p>}
    </DataProvider>
  );
}

Render Props drawbacks

  • Nested functions can make JSX harder to read.
  • Multiple render-prop layers can become difficult to maintain.
  • Hooks often provide a simpler way to share stateful logic in modern function components.

What are Compound Components?

Compound Components are a group of components designed to work together as one logical component. A parent component usually owns shared state, while child components access that state through context or another composition mechanism.

function Tabs() {
  return (
    <TabsRoot>
      <TabsList>
        <TabsTrigger value="overview">Overview</TabsTrigger>
        <TabsTrigger value="settings">Settings</TabsTrigger>
      </TabsList>
      <TabsContent value="overview">Overview content</TabsContent>
      <TabsContent value="settings">Settings content</TabsContent>
    </TabsRoot>
  );
}

Compound Components with Context

Context is a natural fit because the root component can provide shared state and child components can consume it without passing every value through every layer.

const TabsContext = createContext(null);

function TabsRoot({ children }) {
  const [value, setValue] = useState("overview");

  return (
    <TabsContext.Provider value={{ value, setValue }}>
      {children}
    </TabsContext.Provider>
  );
}

function TabsTrigger({ value, children }) {
  const context = useContext(TabsContext);

  return (
    <button onClick={() => context.setValue(value)}>
      {children}
    </button>
  );
}

Designing a compound component API

The goal is to make the API read naturally while hiding the internal coordination. A good compound component gives consumers flexible composition without requiring them to understand the internal state implementation.

Enforcing correct usage

A custom hook can validate that a child is used inside the correct provider.

function useTabsContext() {
  const context = useContext(TabsContext);

  if (!context) {
    throw new Error("Tabs components must be used inside TabsRoot");
  }

  return context;
}

cloneElement and compound components

React.cloneElement can be used to add props to child elements, but it couples the parent to the exact child structure. Context is often easier for deeply nested compound component APIs because children do not need to be direct descendants in the implementation.

Render Props vs HOC vs Custom Hooks

PatternHow logic is sharedTypical style
HOCWraps a componentComponent enhancement
Render PropsCalls a consumer-provided functionBehavior plus custom rendering
Custom HookReturns reusable stateful logicModern function components
Compound ComponentsShared state across a component familyFlexible component API

Real-world examples

Tabs, accordions, dropdowns, menus, modals, select components, and headless UI libraries can benefit from compound component designs. Render Props are more common in legacy code but remain useful when the consumer needs complete control over rendering.

Common mistakes

  • Making a compound component API unnecessarily complex.
  • Using context for every small piece of state.
  • Creating deeply nested render-prop functions.
  • Using cloneElement when a simpler composition or context design would be clearer.
  • Not validating that child components are used inside their required provider.

Interview questions

  • What is the Render Props pattern?
  • What is a Compound Component?
  • How can Context support Compound Components?
  • What are the drawbacks of Render Props?
  • HOC vs Render Props vs Custom Hooks?
  • When would you design a component as a Compound Component?

Key takeaways

  • Render Props share behavior through a rendering function.
  • Compound Components provide a coordinated component API.
  • Context is commonly used for shared compound-component state.
  • Custom Hooks are often preferable for reusable logic, while Compound Components are useful for reusable UI APIs.

Comments & Ratings (0)

Log in or create a student account to comment and rate this article.

Be the first to comment on this article.

Never miss a new post 📬

Get an email whenever a new article, project, cheatsheet or video drops.

✅

ℹ️