Skip to content

Commit ae10f4d

Browse files
authored
breaking: state mutations inside the template are no longer allowed (#13660)
* breaking: state mutations inside the template are no longer allowed * fix test * fix test * lint * update error message * fix test
1 parent 966a6bd commit ae10f4d

File tree

8 files changed

+37
-6
lines changed

8 files changed

+37
-6
lines changed

.changeset/wild-chairs-build.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'svelte': patch
3+
---
4+
5+
breaking: state mutations inside the template are no longer allowed

documentation/docs/98-reference/.generated/client-errors.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,5 +125,5 @@ Reading state that was created inside the same derived is forbidden. Consider us
125125
### state_unsafe_mutation
126126

127127
```
128-
Updating state inside a derived or logic block expression is forbidden. If the value should not be reactive, declare it without `$state`
128+
Updating state inside a derived or a template expression is forbidden. If the value should not be reactive, declare it without `$state`
129129
```

packages/svelte/messages/client-errors/errors.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,4 +82,4 @@
8282
8383
## state_unsafe_mutation
8484

85-
> Updating state inside a derived or logic block expression is forbidden. If the value should not be reactive, declare it without `$state`
85+
> Updating state inside a derived or a template expression is forbidden. If the value should not be reactive, declare it without `$state`

packages/svelte/src/internal/client/errors.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -343,12 +343,12 @@ export function state_unsafe_local_read() {
343343
}
344344

345345
/**
346-
* Updating state inside a derived or logic block expression is forbidden. If the value should not be reactive, declare it without `$state`
346+
* Updating state inside a derived or a template expression is forbidden. If the value should not be reactive, declare it without `$state`
347347
* @returns {never}
348348
*/
349349
export function state_unsafe_mutation() {
350350
if (DEV) {
351-
const error = new Error(`state_unsafe_mutation\nUpdating state inside a derived or logic block expression is forbidden. If the value should not be reactive, declare it without \`$state\``);
351+
const error = new Error(`state_unsafe_mutation\nUpdating state inside a derived or a template expression is forbidden. If the value should not be reactive, declare it without \`$state\``);
352352

353353
error.name = 'Svelte error';
354354
throw error;

packages/svelte/src/internal/client/reactivity/effects.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -326,7 +326,7 @@ export function template_effect(fn) {
326326
value: '{expression}'
327327
});
328328
}
329-
return render_effect(fn);
329+
return block(fn);
330330
}
331331

332332
/**
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { flushSync } from 'svelte';
2+
import { test } from '../../test';
3+
4+
export default test({
5+
compileOptions: {
6+
dev: true
7+
},
8+
9+
test({ assert, target }) {
10+
const button = target.querySelector('button');
11+
12+
assert.throws(() => {
13+
button?.click();
14+
flushSync();
15+
}, /state_unsafe_mutation/);
16+
}
17+
});
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<script>
2+
let items = $state([]);
3+
</script>
4+
5+
<button onclick={() => items.push(3, 2, 1)}>Add</button>
6+
{JSON.stringify(items.sort())}

packages/svelte/tests/runtime-runes/samples/store-unsubscribe-not-referenced-after/main.svelte

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
<script>
2+
import { untrack } from "svelte";
23
import { writable, derived } from "svelte/store";
34
45
const obj = writable({ a: 1 });
@@ -7,7 +8,9 @@
78
89
function watch (prop) {
910
return derived(obj, (o) => {
10-
count++;
11+
untrack(() => {
12+
count++;
13+
});
1114
return o[prop];
1215
});
1316
}

0 commit comments

Comments
 (0)