useComponentSlots: Web Component-style Slots for React

Mike Ritchie
2 min readFeb 18, 2021
Photo by Markus Spiske from Pexels

Here’s the problem: You want to have a React component with a template that has defined multiple subsections for input content, not just a single children prop; how would you pass that content in?

Say you have a page component that has space for a sidebar, a title block, and the main content.

The standard way in React is to use props:

In a vanilla Javascript web component, the template itself defines placeholders for content known as “slots”.

You can then just wrap the component tag around all your child content, including the content that should go into the placeholders:

To me, this is much more straightforward than the standard React method because it’s very declarative. It also has some other advantages:

  • You can easily declare default content in the slots’ template in case the HTML usage of the component doesn’t include them.
  • You don’t need to make sure that there’s only a single top-level element like you do in the React props. One or more elements can share the same slot attribute value, and will all go into the appropriate location in the template.

To that end, I set out to create a custom React hook that would follow this approach and in February 2021 useComponentSlots was born! It’s still a work in progress, but it’s functional and I’m super pleased with it. To use, simply:

1: Install the package:

npm install use-componentslots;

2: Import it into your React component:

import useComponentSlots from 'use-componentslots';

3: Then, simply use the hook in your component’s template:

As you can see, it largely follows the vanilla Javascript approach, with the exception of the capitalized <Slot> that custom components require in React. The hook also has an advanced feature that makes it easy to suppress portions of the component template if they’re empty of children:

In the above example, the aside element in the template will not render because the component using it doesn’t have any children with the slot attribute value ‘sidebar’.

This hook definitely scratched an itch for me and will be a tool in my toolbox for future projects. If you’d like to learn more about it you can check it out at https://github.com/starkraving/slotted-react-component

Cheers!

--

--

Mike Ritchie

I’m a fullstack web developer with a professional passion for user experience and a personal passion for comic books and D&D.