Svelte

How to Handle Reactivity in Svelte

Sponsor

Svelte, like most frontend frameworks, is a reactive language. That means data updates translate straight into UI updates. Let's look at how reactivity works in Svelte.

If you're brand new to Svelte, read my guide on getting started with Svelte here.

Reactivity in Svelte

At its most basic, variables are generally reactive in Svelte. For example, creating a component like this will result in a live updating counter displayed within the button:

<script> let x = 0; const addToCounter = function() { ++x; } </script> <button id="counter" on:click="{addToCounter}">{x}</button> <style> button { background: #ffb334; border-radius: 8px; border: none; font-weight: bold; cursor: pointer; padding: 0.5rem 2rem; color: white; font-size: 1.5rem; } </style>

Above, x is increased by one every time the button is clicked. We do this with on:click="{addToCounter}". The {x} displayed in #counter is automatically increased and displays the new value on every click.

In that way, Svelte provides reactivity out of the box - so it's really easy to intuitively understand what's going on. Svelte also provides some more advanced reactivity features.

Reactive Calculations

In some scenarios, we want to update a value like x, and then do a calculation on it. We may then display that within our UI somewhere. For example:

<script> let x = 0; let bigX = x * 2; const addToCounter = function() { ++x; } </script> <button id="counter" on:click="{addToCounter}">{bigX}</button> <style> button { background: #ffb334; border-radius: 8px; border: none; font-weight: bold; cursor: pointer; padding: 0.5rem 2rem; color: white; font-size: 1.5rem; } </style>

Above, we want to show our calculated bigX value within the button tag, which should equal x * 2. Upon clicking the button, x will increase by one, and therefore we'd expect bigX to also react.

However, in Svelte this will not work, as calculated values like this aren't inherently reactive. As such, we need to tell Svelte that bigX should also react. To do that, we replace let with $:.

The below code will now update bigX every time x is updated, and display it within our button:

<script> let x = 0; $: bigX = x * 2; const addToCounter = function() { ++x; } </script> <button id="counter" on:click="{addToCounter}">{bigX}</button> <style> button { background: #ffb334; border-radius: 8px; border: none; font-weight: bold; cursor: pointer; padding: 0.5rem 2rem; color: white; font-size: 1.5rem; } </style>

Reactivity Principles in Svelte

Svelte intelligently understands that if $: bigX = x * 2, and we want bigX to be reactive, that it should only update if x is updated.

Reactive blocks in Svelte

In the same way that we can make independent variables run again whenever something within them changes, we can do the same for block statements. For example, let's say we want to check if x is equal to 5. If we write the following, it won't do anything:

let x = 0; if(x === 5) { console.log(`x is ${x}!`); } const addToCounter = function() { ++x; }

That's because on initiation, x is 0, and the if statement only runs once. If we want it to run every time x updates, we add $: to the start:

let x = 0; $: if(x === 5) { console.log(`x is ${x}!`); } const addToCounter = function() { ++x; }

The same can be done with curly bracket block statements alone. For example, the below code console logs x any time it changes:

let x = 0; $: { console.log(x); } const addToCounter = function() { ++x; }

Out of all the frontend frameworks, Svelte perhaps makes reactivity the most easy. If you've enjoyed this article, you can find more Svelte content here.

Last Updated Tuesday, 5 April 2022
Johnny Simpson
Johnny Simpson

More Tips and Tricks Svelte

Subscribe for Weekly Dev Tips

Subscribe to our weekly newsletter, to stay up to date with our latest web development and software engineering posts via email. You can opt out at any time.

Not a valid email