React.js
Compound Components

Compound Components

This is design pattern that allows you to create components that share state and logic without having to use a higher order component or render props. At the same time, it allows you to have a lot of flexibility in how you render the component.

Implementation

CompoundComponents.tsx
import { createContext, useContext, useState } from "react";
 
const ParentContext = createContext({ count: 0 });
 
const ParentComponent = ({ children }) => {
  const [count, setCount] = useState(0);
 
  return (
    <ParentContext.Provider value={{ count }}>
      {children}
      <button onClick={() => setCount((state) => state + 1)}>Add one</button>
    </ParentContext.Provider>
  );
};
 
const ShowCount = () => {
  const { count } = ParentComponent.useContext();
  return <div>count: {count}</div>;
};
 
const AddTwo = () => {
  const { count } = ParentComponent.useContext();
  return <div>count plus two: {count + 2}</div>;
};
 
ParentComponent.AddTwo = AddTwo;
ParentComponent.ShowCount = ShowCount;
ParentComponent.useContext = () => useContext(ParentContext);
 
export const Parent = ParentComponent;

Usage

import { Parent } from "#components";
 
<div>
  <Parent>
    <Parent.ShowCount />
    <Parent.AddTwo />
    <div style={{ background: "yellow" }}>
      <Parent.ShowCount />
    </div>
  </Parent>
</div>;
💡

As you can see, you can reuse the same child component in differnet order, context and multiple times. Also we exported all components that works together as a single component just for convenience.

Demo

count: 0
count plus two: 2
count: 0