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.
Top comments (4)
Playground
Cobbled together by peeking at
other than that I haven't used Solid.js a lot (I've spent considerably more time with Svelte). Really the most magic here is that
x()
inbigX
tracksbigX()
invocations and updates them wheneversetX()
is executed.(The big difference to React is that
Counter
only runs once to set everything up - past that it just plain reactivity.)Svelte adds reactivity by extending the language with reactive declarations and statements (and lets not forget about stores (Solid's stores)).
I guess it ultimately comes down to personal preference!
Svelte should have been called react
maybe it should be called reacte