DEV Community

Nathan
Nathan

Posted on • Originally published at natclark.com

Working With Dynamic Components in Svelte

Svelte offers multiple special elements that we can use to write cleaner and more efficient code.

One such special element is the very powerful <svelte:component>. It can be used to dynamically render a component and switch to rendering a different component on demand.

To better understand this, consider the following code:

{#if fruit === `apple`}
    <Apple />
{:else if fruit === `banana`}
    <Banana />
{:else if fruit === `pumpkin`}
    <Pumpkin />
{/if}
Enter fullscreen mode Exit fullscreen mode

The issue with this approach is that it doesn't scale nicely. In this example, a fruit component is dynamically rendered based on the value of fruit, each time the variable changes.

But what if you had a hundred fruits? Well, now you're dealing with hundreds of lines of code. And managing those hundreds of lines, especially with more complex conditionals, is going to be a real mess.

So, this is where <svelte:component> comes in!

Here's an example of how we can use it to dynamically render our fruit components:

<script>
    import Apple from './Apple.svelte';
    import Banana from './Banana.svelte';
    import Pumpkin from './Pumpkin.svelte';

    const fruits = [
        { id: 0, component: Apple, },
        { id: 1, component: Banana, },
        { id: 2, component: Pumpkin, }
    ];

    let fruit = fruits[0];
</script>

<svelte:component this={fruit.component} />
Enter fullscreen mode Exit fullscreen mode

That's much better! Now, no matter how many fruits we have, all we need is just one <svelte:component>, potentially shaving off many redundant lines of code.

Just remember to pass a valid component or a falsy value to the this prop!

Conclusion

Svelte has a lot of useful and unique features, and it can take some time to learn them all and get familiar with using them.

Special elements like the dynamic component can be very powerful, and I hope it helps you optimize your code a bit.

Discussion (0)