Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In Svelte JS, how does reactive variable work if some variable is just printed but doesn't participate in giving out a value?

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?

like image 592
nonopolarity Avatar asked Dec 13 '22 09:12

nonopolarity


1 Answers

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");
}
like image 163
rixo Avatar answered May 29 '23 16:05

rixo