Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Svelte internals: how does reactive declaration syntax work

Tags:

svelte

Regarding reactive declarations in svelte like $: doubled = count*2, it states in the svelte tutorial that

Don't worry if this looks a little alien. It's valid (if unconventional) JavaScript, which Svelte interprets to mean 're-run this code whenever any of the referenced values change'

The conventional javascript feature refrences seems to be labels (please confirm)

Please explain how this is done by the svelte compiler in simple words and provide a reference to the place in the compiler code where this happens [or starts to happen]

There is a githb issue open to explain svelte internals eventually.

like image 266
tjb Avatar asked Jul 27 '19 05:07

tjb


People also ask

How does Svelte reactivity work?

Under-the-hood, Svelte keeps the DOM in sync with the application state and updates the value of the component whenever the value of the variable changes. Generally, for assigned variables, you do not need any additional setup to make them reactive.

Is Svelte reactive?

At the heart of Svelte is a powerful system of reactivity for keeping the DOM in sync with your application state — for example, in response to an event. Svelte 'instruments' this assignment with some code that tells it the DOM will need to be updated.

Are Svelte props reactive?

Svelte's reactivity not only keeps the DOM in sync with your application's variables as shown in the previous section, it can also keep variables in sync with each other using reactive declarations.

What is $$ in Svelte?

$$props references all props that are passed to a component, including ones that are not declared with export . It is not generally recommended, as it is difficult for Svelte to optimise. But it can be useful in rare cases – for example, when you don't know at compile time what props might be passed to a component.

How do I declare a reactive variable in svelte?

In Svelte, there's a special way to do this. Instead of declaring a variable with let, we will use $:. This is a labeled statement (it's valid JS), and it's used by the compiler to let it know that a reactive variable is being declared, and it depends on all the variables that are added to the expression. In our example:

How does svelte react to changes in script?

The change is also rendered in the {bookCount}. In other words, Svelte will make sure that if the value of a variable changes in our script code, the same should be reflected in the DOM. Note that Svelte’s reactivity triggers only at the time of assignment using = operator.

What is reactivity in svelte?

In other words, Svelte will make sure that if the value of a variable changes in our script code, the same should be reflected in the DOM. Note that Svelte’s reactivity triggers only at the time of assignment using = operator.

Why is svelte asking me to re-run this code?

Don't worry if this looks a little alien. It's valid (if unconventional) JavaScript, which Svelte interprets to mean 're-run this code whenever any of the referenced values change'. Once you get used to it, there's no going back.


Video Answer


1 Answers

It is indeed the label syntax.

Javascript labels are seeing little to no use, so it was an elegant way to make create a simple syntax as well making sure it would play nice with linters and IDEs.

Where can you find the code :

Once the code is compiled, you can find the reactive declarations in the state update part of the component lifecycle. However this code is not executed between the beforeUpdate and afterUpdate which are related to the DOM update. If you change values in those callbacks, you might get some wacky results as the reactive statements may not be updated.

You can find it in the code if you look for $$self.$$.update.

How it works :

The compiler is analyzing those statements to find which variables to observe for changes. Those variables being everything right of the assignment operator, or every argument in a function call. It is worth noting that const variables are not observed as they are never supposed to change.

$: doubled = count * 2;

will compile to

if ($$dirty.count) { $$invalidate('doubled', doubled = count * 2); }

$$dirty is the argument received by the update lifecycle, it is an object containing properties for each variables potentially modified, that are set to 1 when $$invalidate is called on it.

Svelte then add thoses statements at the end of the update part of the lifecycle, and condition their execution on the changes of at least one of the aforementioned observed variables.

Svelte is also ordering those statements in a topological order. This means that a reactive statement making use of another reactive statement results is going to be evaluated after. Regardless in which order you put them in your code.

$: quadrupled = doubled * 2;
$: doubled = count * 2;

will still correctly compile to

if ($$dirty.count) { $$invalidate('doubled', doubled = count * 2); }
if ($$dirty.doubled) { $$invalidate('quadrupled', quadrupled = doubled * 2); }

Hope it helps clear things up.

like image 105
Morphyish Avatar answered Oct 18 '22 23:10

Morphyish