Skip to content

Commit a7b61c0

Browse files
authored
docs: use a canvas demo for $effect (#10745)
* use a canvas demo for effect docs * use js block * update text * fix
1 parent ec25208 commit a7b61c0

File tree

1 file changed

+39
-29
lines changed
  • sites/svelte-5-preview/src/routes/docs/content/01-api

1 file changed

+39
-29
lines changed

sites/svelte-5-preview/src/routes/docs/content/01-api/02-runes.md

Lines changed: 39 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -196,48 +196,58 @@ In essence, `$derived(expression)` is equivalent to `$derived.by(() => expressio
196196

197197
## `$effect`
198198

199-
To run side-effects like logging or analytics whenever some specific values change, or when a component is mounted to the DOM, we can use the `$effect` rune:
199+
To run _side-effects_ when the component is mounted to the DOM, and when values change, we can use the `$effect` rune ([demo](/#H4sIAAAAAAAAE31T24rbMBD9lUG7kAQ2sbdlX7xOYNk_aB_rQhRpbAsU2UiTW0P-vbrYubSlYGzmzMzROTPymdVKo2PFjzMzfIusYB99z14YnfoQuD1qQh-7bmdFQEonrOppVZmKNBI49QthCc-OOOH0LZ-9jxnR6c7eUpOnuv6KeT5JFdcqbvbcBcgDz1jXKGg6ncFyBedYR6IzLrAZwiN5vtSxaJA-EzadfJEjKw11C6GR22-BLH8B_wxdByWpvUYtqqal2XB6RVkG1CoHB6U1WJzbnYFDiwb3aGEdDa3Bm1oH12sQLTcNPp7r56m_00mHocSG97_zd7ICUXonA5fwKbPbkE2ZtMJGGVkEdctzQi4QzSwr9prnFYNk5hpmqVuqPQjNnfOJoMF22lUsrq_UfIN6lfSVyvQ7grB3X2mjMZYO3XO9w-U5iLx42qg29md3BP_ni5P4gy9ikTBlHxjLzAtPDlyYZmRdjAbGq7HprEQ7p64v4LU_guu0kvAkhBim3nMplWl8FreQD-CW20aZR0wq12t-KqDWeBywhvexKC3memmDwlHAv9q4Vo2ZK8KtK0CgX7u9J8wXbzdKv-nRnfF_2baTqlYoWUF2h5efl9-n0O6koAMAAA==)):
200200

201201
```svelte
202202
<script>
203-
let count = $state(0);
204-
let doubled = $derived(count * 2);
203+
let size = $state(50);
204+
let color = $state('#ff3e00');
205+
206+
let canvas;
205207
206208
$effect(() => {
207-
console.log({ count, doubled });
209+
const context = canvas.getContext('2d');
210+
context.clearRect(0, 0, canvas.width, canvas.height);
211+
212+
// this will re-run whenever `color` or `size` change
213+
context.fillStyle = color;
214+
context.fillRect(0, 0, size, size);
208215
});
209216
</script>
210217
211-
<button on:click={() => count++}>
212-
{doubled}
213-
</button>
214-
215-
<p>{count} doubled is {doubled}</p>
218+
<canvas bind:this={canvas} width="100" height="100" />
216219
```
217220

218-
`$effect` will automatically subscribe to any `$state` or `$derived` values it reads _synchronously_ and reruns whenever their values change — that means, values after an `await` or inside a `setTimeout` will _not_ be tracked. `$effect` will run after the DOM has been updated.
221+
The function passed to `$effect` will run when the component mounts, and will re-run after any changes to the values it reads that were declared with `$state` or `$derived` (including those passed in with `$props`). Re-runs are batched (i.e. changing `color` and `size` in the same moment won't cause two separate runs), and happen after any DOM updates have been applied.
219222

220-
```svelte
221-
<script>
222-
let count = $state(0);
223-
let doubled = $derived(count * 2);
223+
Values that are read asynchronously — after an `await` or inside a `setTimeout`, for example — will _not_ be tracked. Here, the canvas will be repainted when `color` changes, but not when `size` changes ([demo](/#H4sIAAAAAAAAE31T24rbMBD9lUG7kCxsbG_LvrhOoPQP2r7VhSjy2BbIspHGuTT436tLnMtSCiaOzpw5M2dGPrNaKrQs_3VmmnfIcvZ1GNgro9PgD3aPitCdbT8a4ZHCCiMH2pS6JIUEVv5BWMOzJU64fM9evswR0ave3EKLp7r-jFm2iIwri-s9tx5ywDPWNQpaLl9gvYFz4JHotfVqmvBITi9mJA3St4gtF5-qWZUuvEQo5Oa7F8tewT2XrIOsqL2eWpRNS7eGSkpToFZaOEilwODKjBoOLWrco4FtsLQF0XLdoE2S5LGmm6X6QSflBxKod8IW6afssB8_uAslndJuJNA9hWKw9VO91pmJ92XunHlu_J1nMDk8_p_8q0hvO9NFtA47qavcW12fIzJBmM26ZG9ZVjKIs7ke05hdyT0Ixa11Ad-P6ZUtWbgNheI7VJvYQiH14Bz5a-SYxvtwIqHonqsR12ff8ORkQ-chP70T-L9eGO4HvYAFwRh9UCxS13h0YP2CgmoyG5h3setNhWZF_ZDD23AE2ytZwZMQ4jLYgVeV1I2LYgfZBey4aaR-xCppB8VPOdQKjxes4UMgxcVcvwHf4dzAv9K4ko1eScLO5iDQXQFzL5gl7zdJt-nZnXYfbddXspZYsZzMiNPv6S8Bl41G7wMAAA==)):
224224

225-
$effect(() => {
226-
// runs after the DOM has been updated
227-
// when the component is mounted
228-
// and whenever `count` changes,
229-
// but not when `doubled` changes,
230-
console.log(count);
231-
232-
setTimeout(() => console.log(doubled));
233-
});
234-
</script>
235-
236-
<button on:click={() => count++}>
237-
{doubled}
238-
</button>
225+
```ts
226+
// @filename: index.ts
227+
declare let canvas: {
228+
width: number;
229+
height: number;
230+
getContext(
231+
type: '2d',
232+
options?: CanvasRenderingContext2DSettings
233+
): CanvasRenderingContext2D;
234+
};
235+
declare let color: string;
236+
declare let size: number;
239237

240-
<p>{count} doubled is {doubled}</p>
238+
// ---cut---
239+
$effect(() => {
240+
const context = canvas.getContext('2d');
241+
context.clearRect(0, 0, canvas.width, canvas.height);
242+
243+
// this will re-run whenever `color` changes...
244+
context.fillStyle = color;
245+
246+
setTimeout(() => {
247+
// ...but not when `size` changes
248+
context.fillRect(0, 0, size, size);
249+
}, 0);
250+
});
241251
```
242252

243253
An effect only reruns when the object it reads changes, not when a property inside it changes. If you want to react to _any_ change inside an object for inspection purposes at dev time, you may want to use [`inspect`](#$inspect).

0 commit comments

Comments
 (0)