Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs: expanded svelte/reactivity documentation #14799

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
96 changes: 96 additions & 0 deletions documentation/docs/98-reference/21-svelte-reactivity.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,100 @@ Svelte provides reactive versions of various built-ins like `SvelteMap`, `Svelte
<input bind:value={url.href} />
```

The utilities provided in `svelte/reactivity` are automatically reactive with respect to their properties and methods, as seen in the previous example. As such, they don't need to be wrapped in `$state`. However, if a variable is reassigned, it needs to be wrapped in a `$state` in order for this reassignement to be reactive.

```svelte
<script>
import { SvelteURL } from 'svelte/reactivity';

let url = $state(new SvelteURL('https://example.com/path'));
</script>

<!-- these are reactive... -->
Protocol: {url?.protocol ?? "ftp:"}
<br>
Hostname: {url?.hostname ?? "svelte.dev"}
<br>
Path: {url?.pathname ?? ""}

<hr />

<!-- ...even when reassigning -->
<button
onclick={() => {
url = undefined;
}}
>
Erase
</button>
```

In a similar manner, the values stored inside e.g. `SvelteMap` are not automatically reactive, so if more complex values such as objects are used, they need to be wrapped in a `$state` in order to make their properties reactive as well. Alternatively, the whole object can be rewritten on update, which may actually lead to better performance than deep reactive `$state`.

```svelte
<script>
import { SvelteMap } from 'svelte/reactivity';

const people = new SvelteMap();

// A plain object
const alice = {name: "Alice", age: 18};

// A reactive object
const bob = $state({name: "Bob", age: 21});

people.set("alice", alice);
people.set("bob", bob);
</script>

{#each people.entries() as [id, person] (id)}
Name: {person.name}
<br>
Age: {person.age}
<br>
<br>
{/each}

<hr />

<!-- This will NOT propagate reactively, because alice is a plain object -->
<button
onclick={() => {
people.get("alice").age++;
}}
>
Alice's birthday
</button>

<!-- This WILL propagate reactively, because bob is a reactive object -->
<button
onclick={() => {
people.get("bob").age++;
}}
>
Bob's birthday
</button>

<!-- This WILL propagate reactively, because people is reactive -->
<button
onclick={() => {
people.set("carol", {name: "Carol", age: 0});
marekdedic marked this conversation as resolved.
Show resolved Hide resolved
}}
>
Carol was born
</button>

{#if people.has("carol")}
<!-- This WILL propagate reactively, because we are replacing the whole carol object -->
<button
onclick={() => {
const oldValue = people.get("carol");
people.set("carol", {...oldValue, age: oldValue.age + 1});
}}
>
Carol's birthday
</button>
{/if}
```

> MODULE: svelte/reactivity
Loading