In some cases, a component that immediately modifies a store when loading (or in onMount apparently) can cause exceptions in other components that use that store if they haven't finished mounting yet.
From what I've been able to figure out, the timeline is something like this:
A component loads that uses the store
Another component loads that writes the store when it starts
Writing the store causes the first component to be marked dirty even though the component hasn't actually mounted yet.
A third component loads and calls flush at the end of its init function.
flush goes through and calls update on all the dirty components, which in turn calls $$.fragment.p. But since the first component hasn't actually mounted yet, it's dealing with elements that either don't exist or are not yet added to the DOM and so these may throw exceptions.
I'm not entirely sure if using the client component API is necessary to make this happen. It is necessary in my reproduction, and I'm using it in my real SvelteKit project as well where I first encountered this bug, but in a very different place so I'm not entirely sure.
This can be worked around by waiting a tick to set the store:
let destroyed = false;
onDestroy(() => (destroyed = true));
tick().then(() => {
if (!destroyed) {
$s = true;
}
});
This workaround succeeds in both my reproduction here and in my actual much more complicated app.
It feels like the proper fix is not set ready in the component until it has actually finished mounting, but I'm kind of guessing here and am not sure if that might mess up something else.
Describe the bug
In some cases, a component that immediately modifies a store when loading (or in
onMount
apparently) can cause exceptions in other components that use that store if they haven't finished mounting yet.From what I've been able to figure out, the timeline is something like this:
flush
at the end of its init function.flush
goes through and callsupdate
on all the dirty components, which in turn calls$$.fragment.p
. But since the first component hasn't actually mounted yet, it's dealing with elements that either don't exist or are not yet added to the DOM and so these may throw exceptions.I'm not entirely sure if using the client component API is necessary to make this happen. It is necessary in my reproduction, and I'm using it in my real SvelteKit project as well where I first encountered this bug, but in a very different place so I'm not entirely sure.
This can be worked around by waiting a
tick
to set the store:This workaround succeeds in both my reproduction here and in my actual much more complicated app.
It feels like the proper fix is not set
ready
in the component until it has actually finished mounting, but I'm kind of guessing here and am not sure if that might mess up something else.Reproduction
REPL: https://svelte.dev/repl/1d363ab12dc84315a38472e29f5b2ed3?version=3.47.0 SvelteKit: https://github.com/dimfeld/svelte-update-bug
The code is pretty much the same in the above two.
Logs
No response
System Info
Severity
annoyance