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
pull/13697/head
Dominic Gannaway 3 months ago committed by GitHub
parent 966a6bda05
commit ae10f4d37c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -0,0 +1,5 @@
---
'svelte': patch
---
breaking: state mutations inside the template are no longer allowed

@ -125,5 +125,5 @@ Reading state that was created inside the same derived is forbidden. Consider us
### state_unsafe_mutation ### state_unsafe_mutation
``` ```
Updating state inside a derived or logic block expression is forbidden. If the value should not be reactive, declare it without `$state` Updating state inside a derived or a template expression is forbidden. If the value should not be reactive, declare it without `$state`
``` ```

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

@ -343,12 +343,12 @@ export function state_unsafe_local_read() {
} }
/** /**
* Updating state inside a derived or logic block expression is forbidden. If the value should not be reactive, declare it without `$state` * Updating state inside a derived or a template expression is forbidden. If the value should not be reactive, declare it without `$state`
* @returns {never} * @returns {never}
*/ */
export function state_unsafe_mutation() { export function state_unsafe_mutation() {
if (DEV) { if (DEV) {
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\``); 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\``);
error.name = 'Svelte error'; error.name = 'Svelte error';
throw error; throw error;

@ -326,7 +326,7 @@ export function template_effect(fn) {
value: '{expression}' value: '{expression}'
}); });
} }
return render_effect(fn); return block(fn);
} }
/** /**

@ -0,0 +1,17 @@
import { flushSync } from 'svelte';
import { test } from '../../test';
export default test({
compileOptions: {
dev: true
},
test({ assert, target }) {
const button = target.querySelector('button');
assert.throws(() => {
button?.click();
flushSync();
}, /state_unsafe_mutation/);
}
});

@ -0,0 +1,6 @@
<script>
let items = $state([]);
</script>
<button onclick={() => items.push(3, 2, 1)}>Add</button>
{JSON.stringify(items.sort())}

@ -1,4 +1,5 @@
<script> <script>
import { untrack } from "svelte";
import { writable, derived } from "svelte/store"; import { writable, derived } from "svelte/store";
const obj = writable({ a: 1 }); const obj = writable({ a: 1 });
@ -7,7 +8,9 @@
function watch (prop) { function watch (prop) {
return derived(obj, (o) => { return derived(obj, (o) => {
count++; untrack(() => {
count++;
});
return o[prop]; return o[prop];
}); });
} }

Loading…
Cancel
Save