From a7b61c0f30ee6869cf8f956032146a049e250d20 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Wed, 15 May 2024 14:48:08 -0400 Subject: [PATCH] docs: use a canvas demo for `$effect` (#10745) * use a canvas demo for effect docs * use js block * update text * fix --- .../routes/docs/content/01-api/02-runes.md | 68 +++++++++++-------- 1 file changed, 39 insertions(+), 29 deletions(-) diff --git a/sites/svelte-5-preview/src/routes/docs/content/01-api/02-runes.md b/sites/svelte-5-preview/src/routes/docs/content/01-api/02-runes.md index b9b75d2db1a2..225854381019 100644 --- a/sites/svelte-5-preview/src/routes/docs/content/01-api/02-runes.md +++ b/sites/svelte-5-preview/src/routes/docs/content/01-api/02-runes.md @@ -196,48 +196,58 @@ In essence, `$derived(expression)` is equivalent to `$derived.by(() => expressio ## `$effect` -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: +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==)): ```svelte - - -

{count} doubled is {doubled}

+ ``` -`$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. +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. -```svelte - - - +```ts +// @filename: index.ts +declare let canvas: { + width: number; + height: number; + getContext( + type: '2d', + options?: CanvasRenderingContext2DSettings + ): CanvasRenderingContext2D; +}; +declare let color: string; +declare let size: number; -

{count} doubled is {doubled}

+// ---cut--- +$effect(() => { + const context = canvas.getContext('2d'); + context.clearRect(0, 0, canvas.width, canvas.height); + + // this will re-run whenever `color` changes... + context.fillStyle = color; + + setTimeout(() => { + // ...but not when `size` changes + context.fillRect(0, 0, size, size); + }, 0); +}); ``` 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).