diff --git a/documentation/docs/02-runes/03-$derived.md b/documentation/docs/02-runes/03-$derived.md index 77ab07a0a9..6b38f99746 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 354869f35e..3515a6c4e4 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 6bed3825c7..bd4d23dd15 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 b4da4c79b8..0fc0e7ad16 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; /**