I don't understand what Svelte docs is trying to say about reactive statements

172 Views Asked by At

I have taken this from Svelte docs

It is important to note that the reactive blocks are ordered via simple static analysis at compile time, and all the compiler looks at are the variables that are assigned to and used within the block itself, not in any functions called by them. This means that yDependent will not be updated when x is updated in the following example:

<script>
  let x = 0;
  let y = 0;

  /** @param {number} value */
  function setY(value) {
    y = value;
  }

  $: yDependent = y;
  $: setY(x);
</script>

Moving the line $: yDependent = y below $: setY(x) will cause yDependent to be updated when x is updated.

Refer the Svelte components section in this link https://svelte.dev/docs/svelte-components

Can someone explain me in detail what the docs is trying to say.

In the first case when x is changed setY(x) is triggered, which leads to y being changed but yDependent wont change because I understand that compiler will only look at the variables in the reactive blocks and not inside functions the block is calling.

The same must be true for 2nd case also right ?

I tried both the case and I see that in the first case yDependent stays a constant when x is changing. In the second case yDependent changes when x changes.

3

There are 3 best solutions below

1
Maik Thiele On BEST ANSWER

This is because Svelte's compiler determines the order based on the appearance of the reactive statements, not their functional dependencies. In this specific arrangement, yDependent = y; comes before setY(x);, so yDependent doesn't get updated when y changes as a result of x changing.

$: setY(x);        // Dependent on x
$: yDependent = y; // Dependent on y

In this arrangement, setY(x) runs whenever x changes, which in turn changes y. Now, because yDependent = y; comes after setY(x);, it gets re-evaluated when y changes. Thus, yDependent will change when x changes.

In both cases, the compiler is indeed only looking at the variables in the reactive blocks, not the functions they are calling. However, the difference is in the order in which these reactive statements are evaluated.

0
Manoj Reddi On

This is because Svelte's compiler determines the order based on the appearance of the reactive statements, not their functional dependencies. In this specific arrangement, yDependent = y; comes before setY(x);, so yDependent doesn't get updated when y changes as a result of x changing.

$: setY(x);        // Dependent on x
$: yDependent = y; // Dependent on y
0
freeone On
    $$self.$$.update = () => {
      if ($$self.$$.dirty & /*y*/ 2) {
        $: $$invalidate(2, yD = y);
      }
      if ($$self.$$.dirty & /*x*/ 1) {
        $: setY(x);
        // cant affect yD because of order of compiler output
      }
    };

vs

    $$self.$$.update = () => {
      if ($$self.$$.dirty & /*x*/ 1) {
        $: setY(x);
      }
      // y was marked dirty before this so the block can react
      if ($$self.$$.dirty & /*y*/ 2) {
        $: $$invalidate(2, yD = y);
      }
    };

since the checks happen serially one dirty marked variable has the power to affect the dirty status of all who follow it by running its onupdate statement/expression through $$invalidate calls