fix: warn when a variable is created an read within the same reaction

warn-read-just-created-state
paoloricciuti 2 months ago
parent 2af7ba2156
commit 396305a16d

@ -0,0 +1,5 @@
---
'svelte': patch
---
fix: warn when a variable is created an read within the same reaction

@ -200,6 +200,12 @@ Consider the following code:
To fix it, either create callback props to communicate changes, or mark `person` as [`$bindable`]($bindable).
### reading_just_created_state
```
The variable `%name%` is created and read within `%reaction%`. `%reaction%` will not depend on it.
```
### select_multiple_invalid_value
```

@ -168,6 +168,10 @@ Consider the following code:
To fix it, either create callback props to communicate changes, or mark `person` as [`$bindable`]($bindable).
## reading_just_created_state
> The variable `%name%` is created and read within `%reaction%`. `%reaction%` will not depend on it.
## select_multiple_invalid_value
> The `value` property of a `<select multiple>` element should be an array, but it received a non-array value. The selection will be kept as is.

@ -28,6 +28,7 @@ import { flush_tasks } from './dom/task.js';
import { internal_set, old_values } from './reactivity/sources.js';
import { destroy_derived_effects, update_derived } from './reactivity/deriveds.js';
import * as e from './errors.js';
import * as w from './warnings.js';
import { tracing_mode_flag } from '../flags/index.js';
import { tracing_expressions, get_stack } from './dev/tracing.js';
@ -39,7 +40,6 @@ import {
set_dev_current_component_function
} from './context.js';
import { handle_error, invoke_error_boundary } from './error-handling.js';
import { snapshot } from '../shared/clone.js';
let is_flushing = false;
@ -742,6 +742,13 @@ export function get(signal) {
new_deps.push(signal);
}
}
} else {
w.reading_just_created_state(
signal.label ?? '$state',
(active_reaction.f & DERIVED) !== 0
? `${/** @type {Derived} */ (active_reaction).label ?? '$derived'}`
: '$effect'
);
}
} else if (
is_derived &&

@ -158,6 +158,19 @@ export function ownership_invalid_mutation(name, location, prop, parent) {
}
}
/**
* The variable `%name%` is created and read within `%reaction%`. `%reaction%` will not depend on it.
* @param {string} name
* @param {string} reaction
*/
export function reading_just_created_state(name, reaction) {
if (DEV) {
console.warn(`%c[svelte] reading_just_created_state\n%cThe variable \`${name}\` is created and read within \`${reaction}\`. \`${reaction}\` will not depend on it.\nhttps://svelte.dev/e/reading_just_created_state`, bold, normal);
} else {
console.warn(`https://svelte.dev/e/reading_just_created_state`);
}
}
/**
* The `value` property of a `<select multiple>` element should be an array, but it received a non-array value. The selection will be kept as is.
*/

@ -0,0 +1,13 @@
import { test } from '../../test';
export default test({
compileOptions: {
dev: true
},
async test({ assert, warnings }) {
console.log(warnings);
assert.deepEqual(warnings, [
'The variable `count` is created and read within `derived_count`. `derived_count` will not depend on it.'
]);
}
});

@ -0,0 +1,18 @@
<script>
function test(){
let count = $state(0);
return {
get count(){
return count;
},
set count(c){
count = c
}
};
}
let derived_count = $derived(test().count);
</script>
{derived_count}

@ -0,0 +1,13 @@
import { test } from '../../test';
export default test({
compileOptions: {
dev: true
},
async test({ assert, warnings }) {
console.log(warnings);
assert.deepEqual(warnings, [
'The variable `x` is created and read within `$effect`. `$effect` will not depend on it.'
]);
}
});

@ -0,0 +1,6 @@
<script>
$effect(()=>{
let x = $state(0);
x++;
})
</script>
Loading…
Cancel
Save