Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

701
Visualizações
How do I render components with a switch in Svelte?

I would like to conditionally render components with a switch case statement in Svelte like so:

// index.svelte

<script>
import TextContent from './components/text-content.svelte'
import { someData } from './api/some-data.js'


    const ContentSwitch = (data) => {
        switch (data._type) {
            case 'block':
                return data.children.map((child) => ContentSwitch(child));
            case 'span':
                return (
                    <TextContent>
                        <span slot="text-content">{data.text}</span>
                    </TextContent>
                );
        }
        for (let index = 0; index < data.length; index++) {
            return data.map((item) => ContentSwitch(item));
        }
    };

</script>

<div>
    {#each someData as data}
        {ContentSwitch(data)}
    {/each}
</div>

TextContent component:

// components/text-content.svelte

<slot name="text-content">
    <span />
</slot>

It seems that this approach does not work in Svelte as I'm getting an Unexpected Token error.

Is rendering components with a switch possible in Svelte?

over 4 years ago · Santiago Trujillo
2 Respostas
Responde à pergunta

0

What you are writing there resembles more JSX which is for React. In Svelte you do not write HTML in your JavaScript but instead keep those separate.

What you would do is make a lookup table and use svelte:component to render the correct component:

<script>
  const BlockTypes = {
    "span": TextContent
  }
</script>

{#each children as child}
  {#if child.type === 'block'}
    <svelte:self {...child} />
  {:else}
    <svelte:component this={BlockTypes[child.type]} {...child} />
  {/if}
{/each}

The svelte:self is under the assumptions that this is in itself also an element of type block, for reasons you cannot import a component into itself so you need this special case here. Having this gives you nested blocks out of the box.

In this example you pass all the properties of the child on to the rendered component so you would have to rewrite your components slightly, you could also use slots but that would be a severe mess with named slots.

over 4 years ago · Santiago Trujillo Relatório

0

I think returning the html syntax in the switch 'span' inside the (java)script tag can't work like this.
Actually it's not a switch between different components but rendering differently nested 'data.text' fields all inside a TextContent component?

What's the structure of someData? Assuming it looks something like this

let someData = [
{
  _type: 'block',
  children: [{
  _type: 'span',
  text: 'textValue#1'
  }]
},
{
  _type: 'span',
  text: 'textValue#2'
}
]

A recursive function could be used to get all nested text fields

    function getSpanTexts(dataArr) {
        return dataArr.flatMap(data => {
            switch (data._type) {
            case 'block':
                return getSpanTexts(data.children)
            case 'span':
                return data.text                
        }
        })
    }
    
    $: textArr = getSpanTexts(someData)  // ['textValue#1', 'textValue#2']

The text fields then can be iterated with an each loop inside the html, each rendered inside a TextContent component

<div>
    {#each textArr as text}
         <TextContent>
             <span slot="text-content">{text}</span>
         </TextContent>
    {/each}
</div>

See this working REPL of the code snippets

over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda