Movatterモバイル変換


[0]ホーム

URL:


Skip to content
DEV Community
Log in Create account

DEV Community

cieldon32
cieldon32

Posted on

     

How to use slots in react elegantly

We all know, we can use props to implement component slots. This is a good way, but the props of the components will become more and more.
Also, you can filter the children by element's type, but it isn't a good idea.
And, you can use HOC to wrap the Component, and use Proxy to reduce the children. you can use the subComponent, like:

<YouComponent.SubComponentA>a</YouComponent.SubComponentA>
Enter fullscreen modeExit fullscreen mode

And then, your Component's props will get:

slot: {   SubComponentA: {children, props}}
Enter fullscreen modeExit fullscreen mode

This is a good idea. But There is a better way.
We focus on children, children will be a array, or string, or a ReactElement, or undefined.
The ReactElement has type, you can check the child with the type's name.
You will use your Component like this:

<YouComponent>    <Slot name="SubComponentA">a</Slot>    b</YouComponent>
Enter fullscreen modeExit fullscreen mode

<Slot /> is a component that it render null. And it has a generator function, like this:

import {ReactElement} from 'react'import {SlotProps} from './slot.interface';function Slot(_: SlotProps): ReactElement {  return null as unknown as ReactElement;}Slot.getSlot = function* getCollectionNode(props: SlotProps): any {  yield props.children;};let _Slot = Slot as (props: SlotProps) => JSX.Element;export default _Slot;
Enter fullscreen modeExit fullscreen mode

And then, In your component's code, you can use a hook to reduce the children. The hook like this:

import React from 'react';export function useSlot(children: any) {  const result: Record<string, any> = {    children: []  };  React.Children.map(children, (child: React.ReactElement<any, React.JSXElementConstructor<any>>) => {    if(React.isValidElement(child)){      const type = child.type as any;      const props = child.props;      if(type.name === 'Slot') {        const slot = type.getSlot(child.props);        result[props.name] = slot.next().value;      } else {        result['children'].push(child);      }    } else {      result['children'].push(child);    }  })  return result;}
Enter fullscreen modeExit fullscreen mode

the result of the useSlot(children), will be :

{   SubComponentA: 'a',   children: ['b']}
Enter fullscreen modeExit fullscreen mode

That is my way to use slot in React. Do you have another way? Please tell me.

Top comments(1)

Subscribe
pic
Create template

Templates let you quickly answer FAQs or store snippets for re-use.

Dismiss
CollapseExpand
 
hendrikras profile image
Hendrik Ras
Hi, I'm Hendrik I love JavaScript, so I guess I'm a little crazy. Have been coding professionally for well over 15 years now and as a hobby for even longer.
  • Location
    Utrecht, The Netherlands
  • Work
    Frontend Engineer
  • Joined

This is an interesting approach, Ill give it a try.
Strange that React still doesn't support slots while Vue has it by default.

..

Just a heads up that you can add highlighting to the code blocks if you'd like. Just change:

code block with no colors example

... to specify the language:

code block with colors example

More details in oureditor guide!

Are you sure you want to hide this comment? It will become hidden in your post, but will still be visible via the comment'spermalink.

For further actions, you may consider blocking this person and/orreporting abuse

I am a freelance programmer. I'm interested in working remotely.
  • Location
    China
  • Work
    node full-stack
  • Joined

Trending onDEV CommunityHot

DEV Community

We're a place where coders share, stay up-to-date and grow their careers.

Log in Create account

[8]ページ先頭

©2009-2025 Movatter.jp