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.
More Tips and Tricks for Svelte
- How if-else Logic works in Svelte
- How to Create Components in Svelte
- Each Logic in Svelte
- Getting Started with Events in Svelte
- How to Handle Reactivity in Svelte
- How to pass arguments to events like on:click in Svelte
- How to send events from a child to parent in Svelte
- Creating your first Svelte App with SvelteKit