Cool bindings with Svelte

A framework becomes popular because it’s useful and it brings value. In that perspective, Svelte has pretty cool features to handle everyday needs I’d like to share with you.

Permalink to heading Set state with less code Set state with less code

Look at the following example from the documentation:

<script>
    let count = 0;

    function handleClick() {
        count += 1;
    }
</script>

<button on:click={handleClick}>
    Clicked {count} {count === 1 ? 'time' : 'times'}
</button>

Source: Svelte assignments

There is some beauty here.

No use to import many tools or write any useState. It’s built-in, and the code is amazingly readable.

Permalink to heading Passing elements to child components Passing elements to child components

Maintaining a state between all component tree elements can be a massive pain with reactive frameworks.

I mean you have to write a lot of code, but Svelte is different. Passing elements to children components is straightforward.

<MyChildComponent myProp={myVar} />
<MyGrandChildComponent myProp={myVar} />

The component will re-render when the prop changes, and that covers the whole tree. It does not have to be a var. It can be an expression too.

Permalink to heading Basic binding with no effort Basic binding with no effort

If you want to sync states, you can use Svelte data binding. As usual, the syntax is short, and you can also pass data from children this time. It’s also called “two-way bindings”:

<script>
    let name = '';
</script>

<input bind:value={name} placeholder="enter your name">
<p>Hello {name || 'stranger'}!</p>

Source: Svelte Text Inputs

It means that if var name changes, the input gets updated, and if the user enters its name in the input, the value of the var name changes too.

If we apply this to our nesting components, it could look like that:

<MyChildComponent bind:myProp={myVar} />
<MyGrandChildComponent bind:myProp={myVar} />

All you need for your sync is the simple keyword bind:.

Permalink to heading Stay in context Stay in context

Your component tree might be pretty huge. In that case, passing data, even with data binding, would be exhausting.

To prevent that situation, you can import setContext and getContext from Svelte and start sharing things with the whole family.

Be careful, though. Unlike data binding, it only works downward this time. You set the context in your root component, and all children can access it.

Technically speaking, the context API is a JavaScript map with keys and values. Because Svelte automatically sets an internal state for each component, it’s easy to set and get with this map.

In your root component, you can have:

<script>
    import { setContext } from "svelte";
    
    setContext("YOUR_KEY", {
        foo: "bar"
    });
</script>

And in your child/nested component:

<script>
    import { getContext } from "svelte";

    const { foo } = getContext("YOUR_KEY");
</script>

<p>{foo}</p>

It’s pretty cool but remember that it only makes sense if you have a parent-child relationship (nested components). If you need to share something app-wide, you’d probably use stores instead.

Permalink to heading Use of the dollar Use of the dollar

As we talked about states, there is another excellent feature called “dollar label”. It allows for managing side effects.

Perhaps you don’t know it yet, but any JavaScript statement can have a label:

yaya: var yiha = "Yiha";

It’s a way to associate code instructions with identifiers, but it’s not a significant feature. However, Svelte makes it very unique.

IMHO, they hack js labels, but for the best. Do not expect the same “magic” outside Svelte.

Anyway, when you use $ in front of your code, you tell the compiler that your code should re-run every time the values or the expression changes.

What an excellent way to bind things!

<script>
    let count = 1;

    // the `$:` means 're-run whenever these values change'
    $: doubled = count * 2;
    $: quadrupled = doubled * 2;

    function handleClick() {
        count += 1;
    }
</script>

<button on:click={handleClick}>
    Count: {count}
</button>

<p>{count} * 2 = {doubled}</p>
<p>{doubled} * 2 = {quadrupled}</p>

Source: Reactive declarations

Permalink to heading Wrap up Wrap up

There are many more features in Svelte I’m sure you would love too.

Of course, you can achieve more complex bindings and even store data, but I appreciate how Svelte handles common patterns with less code.

I like Svelte because it’s not just “less code”. You always see the intent. It’s amazingly readable.


I do my best to update all my contents, but keep it mind that "Cool bindings with Svelte" has been published many months ago.