Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Clarify reactivity and functions
  • Loading branch information
colah committed Aug 12, 2021
1 parent 1c58fa9 commit ab48680
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 0 deletions.
@@ -0,0 +1,11 @@
<script>
let x = 0;
function f() {
return x;
}
</script>

<p>x={x}</p>
<p>f()={f()}</p>
<button on:click={()=>{x+=1;}}>Increment</button>
@@ -0,0 +1,11 @@
<script>
let x = 0;
$: f = function f() {
return x;
}
</script>

<p>x={x}</p>
<p>f()={f()}</p>
<button on:click={()=>{x+=1;}}>Increment</button>
@@ -0,0 +1,62 @@
---
title: Reactivity and Functions
---

Svelte reactivity can be slightly unintuitive once you start declaring your own functions.

For example, you might have some code where a reactive variable is becoming a bit complex:

```js
let x = 0;
let k = 1;

$: y = (x*x+k) * (x*x+k) - k;
```

And want to abstract perhaps it's natural to think of there as being a function `f(x)` with `k` as a global variable:

```js
let x = 0;
let k = 1;

function f(x) {
let z = x*x + k;
return z * z - k;
}

$: y = f(x);
```

In this code, `y` will update when `x` changes but not when `k` changes. This is because, from svelte's perspective:

* `y` is a function of `f` and `x`
* `f` is not reactive
* Therefore, `y` only recomputes when `x` changes

To get our intuitive expected behavior, we need to make `f` a reactive variable:

```js
$: f = function (x) {
let z = x*x + k;
return z * z - k;
}
```

Now from svelte's perspective:
* `y` is a function of `f` and `x`
* `f` is a function of `k`
* Therefore, `y` updates when `x` or `k` change.

To summarize:

```js
let a = 0;

let f = () => a; // f will *not* reactively update
$: b = f(); // b will *not* reactively update
$: b = f(a); // b will reactively update (svelte thinks f hasn't changed, but a has)

$: g = () => a; // g will reactively update
$: b = g(); // b will reactively update
$: b = g(a); // b will reactively update
```

0 comments on commit ab48680

Please sign in to comment.