Skip to content

Commit 8ad9295

Browse files
authored
docs: hints on preserving reactivity (#14514)
1 parent aac929d commit 8ad9295

File tree

1 file changed

+48
-7
lines changed

1 file changed

+48
-7
lines changed

documentation/docs/02-runes/02-$state.md

Lines changed: 48 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -36,12 +36,7 @@ let todos = $state([
3636
...modifying an individual todo's property will trigger updates to anything in your UI that depends on that specific property:
3737

3838
```js
39-
// @filename: ambient.d.ts
40-
declare global {
41-
const todos: Array<{ done: boolean, text: string }>
42-
}
43-
44-
// @filename: index.js
39+
let todos = [{ done: false, text: 'add more todos' }];
4540
// ---cut---
4641
todos[0].done = !todos[0].done;
4742
```
@@ -64,6 +59,17 @@ todos.push({
6459

6560
> [!NOTE] When you update properties of proxies, the original object is _not_ mutated.
6661
62+
Note that if you destructure a reactive value, the references are not reactive — as in normal JavaScript, they are evaluated at the point of destructuring:
63+
64+
```js
65+
let todos = [{ done: false, text: 'add more todos' }];
66+
// ---cut---
67+
let { done, text } = todos[0];
68+
69+
// this will not affect the value of `done`
70+
todos[0].done = !todos[0].done;
71+
```
72+
6773
### Classes
6874

6975
You can also use `$state` in class fields (whether public or private):
@@ -85,7 +91,42 @@ class Todo {
8591
}
8692
```
8793

88-
> [!NOTE] The compiler transforms `done` and `text` into `get`/`set` methods on the class prototype referencing private fields.
94+
> [!NOTE] The compiler transforms `done` and `text` into `get`/`set` methods on the class prototype referencing private fields. This means the properties are not enumerable.
95+
96+
When calling methods in JavaScript, the value of [`this`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this) matters. This won't work, because `this` inside the `reset` method will be the `<button>` rather than the `Todo`:
97+
98+
```svelte
99+
<button onclick={todo.reset}>
100+
reset
101+
</button>
102+
```
103+
104+
You can either use an inline function...
105+
106+
```svelte
107+
<button onclick=+++{() => todo.reset()}>+++
108+
reset
109+
</button>
110+
```
111+
112+
...or use an arrow function in the class definition:
113+
114+
```js
115+
// @errors: 7006 2554
116+
class Todo {
117+
done = $state(false);
118+
text = $state();
119+
120+
constructor(text) {
121+
this.text = text;
122+
}
123+
124+
+++reset = () => {+++
125+
this.text = '';
126+
this.done = false;
127+
}
128+
}
129+
```
89130

90131
## `$state.raw`
91132

0 commit comments

Comments
 (0)