You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: sites/svelte-5-preview/src/routes/docs/content/01-api/02-runes.md
+73-22Lines changed: 73 additions & 22 deletions
Original file line number
Diff line number
Diff line change
@@ -335,49 +335,100 @@ In general, `$effect` is best considered something of an escape hatch — useful
335
335
336
336
> For things that are more complicated than a simple expression like `count * 2`, you can also use [`$derived.by`](#$derived-by).
337
337
338
-
When reacting to a state change and writing to a different state as a result, think about if it's possible to use callback props instead.
338
+
You might be tempted to do something convoluted with effects to link one value to another. The following example shows two inputs for "money spent" and "money left" that are connected to each other. If you update one, the other should update accordingly. Don't use effects for this ([demo](/#H4sIAAAAAAAACpVRy2rDMBD8lWXJwYE0dg-9KFYg31H3oNirIJBlYa1DjPG_F8l1XEop9LgzOzP7mFAbSwHF-4ROtYQCL97jAXn0sQh3skx4wNANfR2RMtS98XyuXMWWGLhjZUHCa1GcVix4cgwSdoEVU1bsn4wl_Y1I2kS6inekNdWcZXuQZ5giFDWpfwl5WYyT2fynbB1g1UWbTVbm2w6utOpKNq1TGucHhri6rLBX7kYVwtW4RtyVHUhOyXeGVj3klLxnyJP0i8lXNJUx6en-v6A48K85kTimpi0sYj-yAo-Wlh9FcL1LY4K3ahSgLT1OC3ZTXkBxfKN2uVC6T5LjAduuMdpQg4L7geaP-RNHPuClMQIAAA==)):
Instead, use callbacks where possible ([demo](/#H4sIAAAAAAAACo2SP2-DMBDFv8rp1CFR84cOXQhU6p6tY-ngwoEsGWPhI0pk8d0rG5yglqGj37v7veMJh7VUZDH9dKhFS5jiuzG4Q74Z_7AXUky4Q9sNfemVzJa9NPxW6IIVMXDHQkEOL0lyipo1pBlyeLIsmDbJ9u4oqhdG2A2mLrgedMmy0zCYSjB9eMaGtuC8WXBkPtOBRd8QHy5CDXSa3Jk7HbOfDgjWuAo_U71kz9vr6Bgc2X44orPjow2dKfFNKhSTSW0GBl9iXmAvdEMFQqDmLgBH6HQYyt3ie0doxTV3IWqEY2DN88eohqePvsf9O9mf_if4HMSVXD89NfEI99qvbMs3RdPv4MXYaSWtUeKWQq3oOlfZCJNCcnildlFgWMcdtl0la0kVptwPNH6NP_uzV0acAgAA)):
367
+
368
+
```svelte
353
369
<script>
354
-
let value = $state();
355
-
let value_uppercase = $state();
356
-
function onValueChange(new_text) {
357
-
value = new_text;
358
-
value_uppercase = new_text.toUpperCase();
370
+
let total = 100;
371
+
let spent = $state(0);
372
+
let left = $state(total);
373
+
374
+
function updateSpent(e) {
375
+
spent = +e.target.value;
376
+
left = total - spent;
359
377
}
360
-
</script>
361
378
362
-
<Text {value} {onValueChange}>
363
-
```
379
+
function updateLeft(e) {
380
+
left = +e.target.value;
381
+
spent = total - left;
382
+
}
383
+
</script>
364
384
365
-
If you want to have something update from above but also modify it from below (i.e. you want some kind of "writable `$derived`"), and events aren't an option, you can also use an object with getters and setters.
385
+
<label>
386
+
<input
387
+
type="range"
388
+
value={spent}
389
+
oninput={updateSpent}
390
+
max={total}
391
+
/>
392
+
{spent}/{total} spent
393
+
</label>
394
+
395
+
<label>
396
+
<input
397
+
type="range"
398
+
value={left}
399
+
oninput={updateLeft}
400
+
max={total}
401
+
/>
402
+
{left}/{total} left
403
+
</label>
404
+
```
405
+
406
+
If you need to use bindings, for whatever reason (for example when you want some kind of "writable `$derived`"), consider using getters and setters to synchronise state ([demo](/#H4sIAAAAAAAACo2SQW-DMAyF_4pl7dBqXcsOu1CYtHtvO44dsmKqSCFExFRFiP8-xRCGth52tJ_9PecpA1bakMf0Y0CrasIU35zDHXLvQuGvZJhwh77p2nPoZP7casevhS3YEAM3rAzk8Jwkx9jzjixDDg-eFdMm2S6KoWolyK6ItuCqs2fWjYXOlYrpPTA2tIUhiAVH5iPtWbUX4v1VmY6Okzpzp2OepgNEGu_CT1St2fP2fXQ0juwwHNHZ4ScNmxn1RUaCybR1HUMIMS-wVfZCBYJQ80GAIzRWhvJh9d4RanXLB7Ea4SCsef4Qu1IG68Xu387h9D_GJ2ne8ZXpxTZUv1w994amjxCaMc1Se2dUn0Jl6DaHeFEuhWT_QvUqOlnHHdZNqStNJabcdjR-jt8IbC-7lgIAAA==)):
If you absolutely have to update `$state` within an effect and run into an infinite loop because you read and write to the same `$state`, use [untrack](functions#untrack).
0 commit comments