From 6a2c28c59091f93c483ed4a77d2eaf617d602ae8 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Fri, 1 Nov 2024 03:49:52 -0400 Subject: [PATCH] docs: tweak untrack description, provide an example of usage (#14085) * docs: tweak untrack description, provide an example of usage * link to untrack * add derived docs too --- documentation/docs/02-runes/03-$derived.md | 6 ++++++ documentation/docs/02-runes/04-$effect.md | 2 +- packages/svelte/src/internal/client/runtime.js | 12 +++++++++++- packages/svelte/types/index.d.ts | 12 +++++++++++- 4 files changed, 29 insertions(+), 3 deletions(-) diff --git a/documentation/docs/02-runes/03-$derived.md b/documentation/docs/02-runes/03-$derived.md index 77ab07a0a98b..6b38f9974672 100644 --- a/documentation/docs/02-runes/03-$derived.md +++ b/documentation/docs/02-runes/03-$derived.md @@ -45,3 +45,9 @@ Sometimes you need to create complex derivations that don't fit inside a short e ``` In essence, `$derived(expression)` is equivalent to `$derived.by(() => expression)`. + +## Understanding dependencies + +Anything read synchronously inside the `$derived` expression (or `$derived.by` function body) is considered a _dependency_ of the derived state. When the state changes, the derived will be marked as _dirty_ and recalculated when it is next read. + +To exempt a piece of state from being treated as a dependency, use [`untrack`](svelte#untrack). diff --git a/documentation/docs/02-runes/04-$effect.md b/documentation/docs/02-runes/04-$effect.md index 354869f35ea6..3515a6c4e40b 100644 --- a/documentation/docs/02-runes/04-$effect.md +++ b/documentation/docs/02-runes/04-$effect.md @@ -2,7 +2,7 @@ title: $effect --- -Effects are what make your application _do things_. When Svelte runs an effect function, it tracks which pieces of state (and derived state) are accessed, and re-runs the function when that state later changes. +Effects are what make your application _do things_. When Svelte runs an effect function, it tracks which pieces of state (and derived state) are accessed (unless accessed inside [`untrack`](svelte#untrack)), and re-runs the function when that state later changes. Most of the effects in a Svelte app are created by Svelte itself — they're the bits that update the text in `

hello {name}!

` when `name` changes, for example. diff --git a/packages/svelte/src/internal/client/runtime.js b/packages/svelte/src/internal/client/runtime.js index 6bed3825c758..bd4d23dd15b6 100644 --- a/packages/svelte/src/internal/client/runtime.js +++ b/packages/svelte/src/internal/client/runtime.js @@ -831,7 +831,17 @@ export function invalidate_inner_signals(fn) { } /** - * Use `untrack` to prevent something from being treated as an `$effect`/`$derived` dependency. + * When used inside a [`$derived`](https://svelte.dev/docs/svelte/$derived) or [`$effect`](https://svelte.dev/docs/svelte/$effect), + * any state read inside `fn` will not be treated as a dependency. + * + * ```ts + * $effect(() => { + * // this will run when `data` changes, but not when `time` changes + * save(data, { + * timestamp: untrack(() => time) + * }); + * }); + * ``` * @template T * @param {() => T} fn * @returns {T} diff --git a/packages/svelte/types/index.d.ts b/packages/svelte/types/index.d.ts index b4da4c79b865..0fc0e7ad16d6 100644 --- a/packages/svelte/types/index.d.ts +++ b/packages/svelte/types/index.d.ts @@ -455,7 +455,17 @@ declare module 'svelte' { * */ export function tick(): Promise; /** - * Use `untrack` to prevent something from being treated as an `$effect`/`$derived` dependency. + * When used inside a [`$derived`](https://svelte.dev/docs/svelte/$derived) or [`$effect`](https://svelte.dev/docs/svelte/$effect), + * any state read inside `fn` will not be treated as a dependency. + * + * ```ts + * $effect(() => { + * // this will run when `data` changes, but not when `time` changes + * save(data, { + * timestamp: untrack(() => time) + * }); + * }); + * ``` * */ export function untrack(fn: () => T): T; /**