1. What the heck is a Compound Component?
A Compound Component is a design pattern where you group multiple smaller components together to work as a team, while each part stays flexible and independent.
In React, you use components like:
<Dropdown>
<Dropdown.Toggle>Open</Dropdown.Toggle>
<Dropdown.Menu>
<Dropdown.Item>Edit</Dropdown.Item>
<Dropdown.Item>Delete</Dropdown.Item>
</Dropdown.Menu>
</Dropdown>
2. Why should you care?
Without this pattern, you'd end up with:
- Prop drilling – passing data through 5 levels just to get it to the right spot.
- Giant, rigid components – one massive component with 20 props to handle every possible case.
- Hard-to-read code – no one wants to read a wall of props.
Compound components give you:
- Flexibility – users can add, remove, or reorder pieces.
- Shared state – all pieces can access the same data (like isOpen in a dropdown) without passing props manually.
- Clean, readable JSX – looks like HTML, works like magic.
3. When should you use it? (How to know it's time)
Multiple parts always appear together
Parts share state
Users need to customize layout
4. How to build one? (Example: A Product Card)
import React, { createContext, useContext } from "react";
const ProductContext = createContext();
const ProductCard = ({ product, children }) => {
return (
<ProductContext.Provider value={{ product }}>
<div className="product-card">{children}</div>
</ProductContext.Provider>
);
};
const Image = () => {
const { product } = useContext(ProductContext);
return product?.image ? <img src={product.image} /> : null;
};
const Title = () => {
const { product } = useContext(ProductContext);
return product?.title ? <h3>{product.title}</h3> : null;
};
const Price = () => {
const { product } = useContext(ProductContext);
return product?.price ? <p>${product.price}</p> : null;
};
const AddToCart = () => {
const { product } = useContext(ProductContext);
return <button onClick={() => alert(`Added ${product.title}`)}>Add to Cart</button>;
};
ProductCard.Image = Image;
ProductCard.Title = Title;
ProductCard.Price = Price;
ProductCard.AddToCart = AddToCart;
On homepage (simple):
<ProductCard product={product}>
<ProductCard.Image />
<ProductCard.Title />
</ProductCard>
On wishlist (no price, no cart button):
<ProductCard product={product}>
<ProductCard.Image />
<ProductCard.Title />
</ProductCard>
Rearrange the order:
<ProductCard product={product}>
<ProductCard.Price /> {/* Price first */}
<ProductCard.Title /> {/* Title second */}
<ProductCard.Image /> {/* Image last */}
</ProductCard>
Top comments (0)