Home > Mobile >  Best way to change vue slots pattern into React?
Best way to change vue slots pattern into React?

Time:08-20

In my vue application, i am using slots for some block of contents. Now, i have to migrate my application into react. While exploring react, i got to know props.children will work similar as slot works.

But, i am not sure what will be the proper way to use this pattern in react.

Here is the sample of code in vue

 <template>
    <div >
        <span : :style="badgeStyle">
            <span v-if="shape !=='dot'" >
                <slot>
                    {{text}}
                </slot>
            </span>
        </span>
        <span v-if="shape ==='dot'"  style="margin-left: 8px;">
            <slot name="dotShape">
                {{text}}
            </slot>
        </span>
    </div>
</template>

<script>
 export default {
   name:'sample'
   props: {
     text: { type: string }
   
   }
 
 }
</script>

How to change this vue slot pattern into React using props.children?

CodePudding user response:

There are several patterns in React that correlate closely with Vue slots.

props.children can be used, but only for default slot with no slotProps. For named slot additional props can be used. Default slot content <slot>{{text}}</slot> can be conditionally rendered when no children are provided:

let MyComp = props => (
  ...
  <div >{{props.children ?? props.text}}</div>
  ...
  <div >{{props.named ?? props.text}}</div>
  ...
)

and

<MyComp named={<p>Named content</p>}>
  <p>Default content</p>
</MyComp>

Function as child and function as prop patterns serve the same purpose but allow to replace slots with slotProps. A child can pass parameters to parent scope through a callback:

let MyComp = props => (
  ...
  <div >{{props.children?.('foo') ?? props.text}}</div>
  ...
  <div >{{props.named?.('bar') ?? props.text}}</div>
  ...
)

and

<MyComp named={param => <p>Named content {{param}}</p>}>{
  param => <p>Default content {{param}}</p>
}</MyComp>

CodePudding user response:

Assuming you are using JSX/TSX in functional React

const Component ({text}) => {
    return (
        <div >
            <span : :style="badgeStyle">
                <span v-if="shape !=='dot'" >
                    {{text}}
                </span>
            </span>
            <span v-if="shape ==='dot'"  style="margin-left: 8px;">
                {{text}}
            </span>
        </div>
    )
}

will do what you want. If you are using class component, put it in the render method.

  • Related