From 52ab33206c8d81f5534dd3a2339e7a65502d1750 Mon Sep 17 00:00:00 2001
From: raythurnvoid <53383860+raythurnvoid@users.noreply.github.com>
Date: Thu, 26 Jun 2025 16:39:04 +0100
Subject: [PATCH] Update $effect and testing docs to mention issues with push
on state array
---
documentation/docs/02-runes/04-$effect.md | 67 +++++++++++++++++++++++
documentation/docs/07-misc/02-testing.md | 8 ++-
2 files changed, 74 insertions(+), 1 deletion(-)
diff --git a/documentation/docs/02-runes/04-$effect.md b/documentation/docs/02-runes/04-$effect.md
index 0e129973d58e..28d6be10a3c7 100644
--- a/documentation/docs/02-runes/04-$effect.md
+++ b/documentation/docs/02-runes/04-$effect.md
@@ -321,4 +321,71 @@ Instead, use `oninput` callbacks or — better still — [function bindings](bin
```
+### untrack
+
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](svelte#untrack).
+
+A common mistake is updating the a `$state` array inside effects (for example `arr.push(item)`). This causes an infinite loop because methods like `push` read the array's `length` property (making the effect depend on it) and also modify it (triggering the effect again):
+
+```svelte
+
+```
+
+To fix this, wrap the mutation in `untrack`:
+
+```svelte
+
+```
+
+This applies to all array methods that mutate the array: `push`, `pop`, `shift`, `unshift`, `splice`, etc. The same issue occurs when reassigning a `$state` variable based on its current value, such as `log = [...log, count]`.
+
+Alternatively, if you don't need the array to be reactive (i.e., changes to it don't need to update the UI), you can use a regular variable instead of `$state`:
+
+```svelte
+
+```
\ No newline at end of file
diff --git a/documentation/docs/07-misc/02-testing.md b/documentation/docs/07-misc/02-testing.md
index db99b7077022..a814d6f6a405 100644
--- a/documentation/docs/07-misc/02-testing.md
+++ b/documentation/docs/07-misc/02-testing.md
@@ -147,7 +147,13 @@ test('Effect', () => {
* @param {() => any} getValue
*/
export function logger(getValue) {
- /** @type {any[]} */
+ /**
+ * must not be a `$state`
+ *
+ * @see https://svelte.dev/docs/svelte/$effect#When-not-to-use-$effect-untrack
+ *
+ * @type {any[]}
+ **/
let log = [];
$effect(() => {