The code in https://svelte.dev/repl/f8db4771ba794c658d7c25a6e72d1b46?version=3.18.1

has two "reactive variables":

$: nameUpperCase = name.toUpperCase();

$: if (name === "city") { 
    console.log("RUNNING HERE 01", age);
} else {
    console.log("RUNNING HERE 02", age);
}

if the value of name changes, then nameUpperCase also get changed. This one is easy.

But for the second part, it seems when the value of name or age is changed, then the if line is evaluated. If the age is removed from the console.log(), as in https://svelte.dev/repl/68c2cdea2bfd462caa5ac5519fb8b99d?version=3.18.1 then it doesn't matter if age changes. The if line is not evaluated.

But the age never participate in generating any final value for the if statement. It is merely printed out, and the console.log always return undefined. So what is the rule? Somehow Svelte "magically" gathers all variables after the $:, and then if any of them change, then execute the line after the $:? So even if the variable doesn't participate in forming some final value, it still is considered?

2

There are 2 answers

2
rixo On

The way your question is framed, I think "yes" would be a proper answer.

It works exactly as you've described: When any variable in the reactive block change, then the block gets executed.

That's the rule. Simple. Predictable. See how you've intuited it all correctly by yourself?

It isn't anymore (or any less) magic than having the value of your variables automatically reflected in your view. Svelte already knows about all the (top level) variables in your code for that.

Whether the reative block "produces" a value or not (reactive declaration vs statement) is irrelevant. It's just "all the variables".

If you want to exclude a variable from being watched, then extract the processing that uses it from the reactive block:

// runs when `name` or `age` change
$: if (name === "city") { 
    console.log("RUNNING HERE 01", age);
} else {
    console.log("RUNNING HERE 02", age);
}

const logAge = msg => console.log(msg, age)

// only runs when `name` changes
$: if (name === "city") { 
    logAge("RUNNING HERE 01");
} else {
    logAge("RUNNING HERE 02");
}
1
0xedb On

You're right. Svelte's reactivity is based on assignment.

The API says this:

Any top-level statement (i.e. not inside a block or a function) can be made reactive by prefixing it with the $: . Reactive statements run immediately before the component updates, whenever the values that they depend on have changed.