-
-
Notifications
You must be signed in to change notification settings - Fork 4.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[docs] update warning message for state_referenced_locally
#15171
base: main
Are you sure you want to change the base?
Conversation
|
|
I think let foo = $state({ value : 0 });
let bar = $state(foo);
foo.value++;
console.log(bar.value) // 1 However, it stops updating if
|
That's the kind of response you want to elicit in a warning. Due to quirks in svelte/js, the code the user has written may not behave as expected. The warning is not nuanced because it was meant to be grokable and a url to the docs is provided to encourage them to explore further to ensure they have written code with behaviour they expect. |
The state is reactive, it's the reference that isn't. I think the current wording is more correct than the proposed alteration. |
This is one proposed by @brunnerh. I agree that the current version is correct. But it does not grok well. |
How about this? |
Maybe I'm confused, but isn't the "non-updating" aspect... probably intentional, if using const items = 5
let itemsPerPage = $state(5)
let pages = $state(items / itemsPerPage) // will not update when itemsPerPage does Surely that should be fine, because if I did want to keep them in sync, I would have used const items = 5
let itemsPerPage = $state(5)
let pages = $derived(items / itemsPerPage) // updates along with itemsPerPage, since it is "derived" from it Every time I've seen this warning I've thought "well yeah I know it's not gonna update." |
The goal of the warning is exactly because you might not realize that you are accessing state in it's own scope and might expect to actually update when it changes. |
Right, but then instead of suggesting to use a closure, maybe it should nudge towards // ...
let pages = $state(() => items / itemsPerPage) // no warning
// later
pages = 12 // the desynchronization that was meant to be warned against happened anyway |
What the closure message is hinting to is that if you want to pass a reactive value to some function you need to wrap it in a closure: let count = $state(0);
// wrong
const counter = double_it(count);
//right
const counter = double_it(()=>count); |
I see, thanks for the clarification. I guess then, ideally I think there should be a different warning when the reference is itself inside a let count = $state(0);
const modifiedOutdated = doSomething(count);
// warning:
// This state reference breaks reactivity and will always be equal to the state's initial value.
// Consider using a closure to get the updated value.
const modifiedSnapshot = doSomething($state.snapshot(count));
const getModified = doSomething(() => count);
// no warning
let modifiedState = $state(doSomething(count));
const getModifiedState = $state(doSomething(() => count));
// warning:
// State referenced in another state may lead to unexpected desynchronization.
// Consider using $derived to keep states synced or $state.snapshot to explicitly de-sync.
let modifiedDerived = $derived(doSomething(count)); // or $derived(doSomething(() => count))
let modifiedStateSnapshot = $state(doSomething($state.snapshot(count)));
// no warning |
closes #11883 #13079
I believe there should be better examples for closures. The current example only covers
setContext('count', () => count);
. But there is more than 1 way to create a closure and more than 1 place this warning can appear. For example:REPL
Before submitting the PR, please make sure you do the following
If there is interest. I can create a separate issue for the above.
feat:
,fix:
,chore:
, ordocs:
.packages/svelte/src
, add a changeset (npx changeset
).Tests and linting
pnpm test
and lint the project withpnpm lint