JS Guide
HomeQuestionsTopicsCompaniesResources
BookmarksSearch

Built for developers preparing for JavaScript, React & TypeScript interviews.

ResourcesQuestionsSupport
HomeQuestionsSearchProgress
HomeQuestionsreact
PrevNext

Learn the concept

Advanced Patterns

react
senior
patterns

Explain common React patterns: Compound Components, Render Props, and Custom Hooks.

patterns
compound-components
render-props
custom-hooks
composition
Quick Answer

Compound Components share implicit state between related components (like <select>/<option>). Render Props pass render functions to share code. Custom Hooks extract reusable stateful logic. Today, Custom Hooks are preferred over Render Props for most cases.

Detailed Explanation

Compound Components:

  • Multiple components work together as a unit
  • Share implicit state via Context
  • Flexible, declarative API
  • Examples: Tabs/Tab, Accordion/Panel, Select/Option

Render Props:

  • Component receives function that returns React elements
  • Function receives state/behavior as arguments
  • Enables code reuse without HOCs
  • Largely replaced by hooks

Custom Hooks:

  • Extract stateful logic into reusable functions
  • Can use other hooks
  • Cleaner than render props or HOCs
  • Modern preferred approach

Pattern Evolution:

  • Mixins → HOCs → Render Props → Hooks
  • Hooks solve most use cases more elegantly
  • Compound components remain useful for component APIs

Code Examples

Compound Components patternJSX
// Context for implicit state sharing
const TabsContext = createContext();

function Tabs({ children, defaultTab }) {
  const [activeTab, setActiveTab] = useState(defaultTab);
  
  return (
    <TabsContext.Provider value={{ activeTab, setActiveTab }}>
      <div className="tabs">{children}</div>
    </TabsContext.Provider>
  );
}

function TabList({ children }) {
  return <div className="tab-list">{children}</div>;
}

function Tab({ id, children }) {
  const { activeTab, setActiveTab } = useContext(TabsContext);
  
  return (
    <button 
      className={activeTab === id ? 'active' : ''}
      onClick={() => setActiveTab(id)}
    >
      {children}
    </button>
  );
}

function TabPanels({ children }) {
  return <div className="tab-panels">{children}</div>;
}

function TabPanel({ id, children }) {
  const { activeTab } = useContext(TabsContext);
  if (activeTab !== id) return null;
  return <div className="tab-panel">{children}</div>;
}

// Usage - clean, declarative API
function App() {
  return (
    <Tabs defaultTab="tab1">
      <TabList>
        <Tab id="tab1">First</Tab>
        <Tab id="tab2">Second</Tab>
      </TabList>
      <TabPanels>
        <TabPanel id="tab1">First content</TabPanel>
        <TabPanel id="tab2">Second content</TabPanel>
      </TabPanels>
    </Tabs>
  );
}

Real-World Applications

Use Cases

Design System Architecture

Using compound components for complex UI patterns (Accordion, Tabs, Combobox) in design systems

Flexible API Design

Choosing between prop-based, compound, and hook-based APIs for library components

Pattern Migration

Migrating legacy codebases from HOCs and render props to modern hook-based patterns

Mini Projects

Compound Component Library

advanced

Build a Tabs, Accordion, and Select component using compound component pattern with context

Pattern Refactoring Workshop

intermediate

Take a component using render props and HOCs and refactor to hooks while maintaining the same API

Industry Examples

Headless UI

Uses compound component patterns for accessible, unstyled components

Downshift

Pioneered render props and hooks patterns for accessible combobox/select components

Resources

React Docs - Reusing Logic with Custom Hooks

docs

Kent C. Dodds - Compound Components

article

Related Questions

What are custom hooks and how do you create them?

mid
hooks

What is React Context and when should you use it?

mid
context
Previous
How do Error Boundaries work in React and what are their limitations?
Next
What are Higher-Order Components (HOCs) in React, and why are they less commonly used today?
PrevNext