Slot
Problem
Components hardcode their entire structure, forcing you to create new variants for each content combination. Layout components can’t be reused because you can’t inject custom content into specific areas like headers, footers, or sidebars without modifying the component itself.
Solution
Accept content from parent components through designated insertion points. This creates flexible component APIs where parents control what gets rendered in specific areas.
Example
This demonstrates creating flexible component APIs where parent components can inject custom content into designated slots, making the component reusable across different contexts without creating multiple variants.
// Card component with multiple content slots
function Card({ header, children, footer }) {
return (
<div className="card">
<div className="card-header">{header}</div> {/* Header slot */}
<div className="card-body">{children}</div> {/* Main content slot */}
<div className="card-footer">{footer}</div> {/* Footer slot */}
</div>
);
}
// Parent controls what gets rendered in each slot
<Card header={<h2>Title</h2>} footer={<button>Action</button>}>
<p>Content</p>
</Card>
Benefits
- Makes components highly flexible and reusable across different contexts.
- Allows parent components to control what gets rendered in specific areas.
- Reduces the need to create multiple component variants for different content.
- Enables better composition and inversion of control.
Tradeoffs
- Can make component structure less obvious when content comes from parents.
- May lead to overuse, making components too flexible and hard to understand.
- Requires clear documentation about what slots accept and expect.
- Can complicate prop validation and type checking.