Skip to content

Commit

Permalink
Force reactive state to reevaluate
Browse files Browse the repository at this point in the history
  • Loading branch information
jakelazaroff committed Feb 14, 2024
1 parent fa35caa commit 57f6710
Showing 1 changed file with 54 additions and 0 deletions.
54 changes: 54 additions & 0 deletions svelte/force-reactive-state-to-reevaluate.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# Force reactive state to reevaluate

In Svelte 5, you declare a reactive variable using the [`$state` rune](https://svelte.dev/blog/runes).

```svelte
let something = $state(1);
```

Svelte will track anything that depends on that variable — such as a derived variable, or an effect — and update it whenever the value changes:

```svelte
let something = $state(1);
let doubled = $derived(something * 2);
$effect(() => console.log(something + doubled));
something = 2;
```

In this case, setting `something` to 2 will update `doubled` to 4 and run the effect, logging 6.

Previous verisons of Svelte would use self-assignments (e.g. `something = something`) to update dependents. In Svelte 5, that no longer works — which presents a problem if you're trying to use a class that mutates itself, such as a [Yjs](https://yjs.dev) document:

```svelte
import * as Y from "yjs";
let doc = $state(new Y.Doc());
doc.on("change", () => {
doc = doc;
});
let array = $derived(doc.getArray("my-array"));
$effect(() => console.log(array)); // will never run
array.insert(0, ["val"]);
```

However, it **does** work if you first assign `undefined` to the state:

```svelte
import * as Y from "yjs";
let doc = $state(new Y.Doc());
doc.on("change", () => {
const tmp = doc;
doc = undefined;
doc = tmp;
});
let array = $derived(doc.getArray("my-array"));
$effect(() => console.log(array)); // run whenever the array is changed!
array.insert(0, ["val"]);
```

0 comments on commit 57f6710

Please sign in to comment.