React Slots are a pattern for component composition that allows you to pass components or JSX as children and control how they are rendered in different parts of a component. This pattern is inspired by "slots" in frameworks like Vue.js or Web Components.
React Slots is often implemented by leveraging React context or child filtering to create named slots (Title
, Body
, Footer
) that a parent component like Card
can recognize and render correctly. Here's how you can achieve this:
Implementing React Slots
// Define the Card component and its slots
const Card = ({ children }) => {
// Filter out specific child components based on their type
const title = React.Children.toArray(children).find(child => child.type === Title);
const body = React.Children.toArray(children).find(child => child.type === Body);
const footer = React.Children.toArray(children).find(child => child.type === Footer);
return (
<div className="card">
<div className="card-title">{title}</div>
<div className="card-body">{body}</div>
<div className="card-footer">{footer}</div>
</div>
);
};
// Slot components
const Title = ({ children }) => <h2>{children}</h2>;
const Body = ({ children }) => <p>{children}</p>;
const Footer = ({ children }) => <footer>{children}</footer>;
// Usage
const App = () => {
return (
<Card>
<Title>What is React?</Title>
<Body>
Learn React.
</Body>
<Footer>
<button>Get started</button>
</Footer>
</Card>
);
};
Explanation
-
Card
Component:- Collects
children
and filters them based on each child'stype
property. - Identifies specific slots (
Title
,Body
,Footer
) by comparing the childβstype
with the predefined slot components.
- Collects
-
Slot Components:
-
Title
,Body
, andFooter
act as placeholders. - They are simple components that render their children directly but provide semantic meaning to the
Card
component.
-
-
Usage:
- The child components (
Title
,Body
,Footer
) are slots inside theCard
, enabling clear and declarative composition.
- The child components (
Output HTML
The above setup renders the following HTML:
<div class="card">
<div class="card-title">
<h2>What is React?</h2>
</div>
<div class="card-body">
<p>Learn React.</p>
</div>
<div class="card-footer">
<footer>
<button>Get started</button>
</footer>
</div>
</div>
Benefits
-
Clear API: The use of semantic slot components like
Title
,Body
, andFooter
improves code readability. -
Flexibility: Slots can be reordered, omitted, or extended without modifying the
Card
component. - Reusability: This pattern can be used for any component requiring named slots.
Do comment down π what do you think about this pattern and its use cases.
Top comments (2)
I'm missing something. Shouldn't the title be wrapped in an h2 as this was provided as part of the Title slot render?
My bad. I have updated the final output example. Thanks.