page props are re-set whenever the `session` store is updated, and the `load` function is re-run the first time
See original GitHub issueDescribe the bug
In the docs, in the section about the load
function, it’s stated that:
…if url, session or stuff are used in the function, they will be re-run whenever their value changes… (here)
But this doesn’t seem to be the case. I have the following page in my SvelteKit app:
index.svelte
:
<script lang="ts" context="module">
import type { Load } from '@sveltejs/kit';
export const load: Load = () => {
console.warn('index load function');
return {};
}
</script>
<script lang="ts">
import { session } from '$app/stores';
function changeSession() {
$session.someField = Math.random();
}
</script>
<pre>{JSON.stringify($session, null, 4)}</pre>
<button on:click={changeSession}>
Change $session
</button>
If you click on the “Change $session” button, you’ll see the message “index load function” appearing in the console, which obviously means the load function is re-run, even though session
isn’t used in the load
function. This is inconsistent with the behavior described in the docs.
The strange thing, however, is that from the second time onwards, when the value of the ‘$session’ store changes, the load
function is no longer re-run. This is confusing.
The more severe bug, however, which seems to be related to this one, is that every time the $session
store changes, the page’s props are apparently re-set, which means reactivity is re-triggered throughout the entire page, potentially causing massive problems.
Consider the following:
<script lang="ts" context="module">
import type { Load } from '@sveltejs/kit';
export const load: Load = () => {
console.warn('index load function');
return {
props: {
userBasicInfo: {
id: 2,
}
}
};
}
</script>
<script lang="ts">
import { browser } from '$app/env';
import { session } from '$app/stores';
export let userBasicInfo;
function changeSession() {
$session.someField = Math.random();
}
$: console.log('userBasicInfo changed:', userBasicInfo);
</script>
<pre>{JSON.stringify($session, null, 4)}</pre>
<button on:click={changeSession}>
Change Ssession
</button>
<hr />
{#if browser}
{#await fetch(`https://reqres.in/api/users/${userBasicInfo.id}`).then(r => r.json())}
Loading...
{:then result}
<pre>{JSON.stringify(result, null, 4)}</pre>
{/await}
{/if}
In this setup, whenever you click on the “Change $session” button — which is to say whenever you update the $session
store — the fetch
request in the markup, which uses the userBaicInfo
prop, is re-triggered, even though it obviously shouldn’t. And you can see the userBasicInfo changed: ...
message in the console which proves that it’s because of the userBasicInfo
prop getting re-set.
Reproduction
You can create an empty SvelteKit skeleton project and then copy-paste the two code snippets above into the index.svelte
file, and then npm run dev
=> open your browser and see the behavior for yourself.
Logs
No response
System Info
System:
OS: Windows 10 10.0.19042
CPU: (4) x64 Intel(R) Core(TM) i7-7500U CPU @ 2.70GHz
Memory: 1.09 GB / 7.89 GB
Binaries:
Node: 14.15.0 - C:\Program Files\nodejs\node.EXE
Yarn: 1.22.10 - ~\AppData\Roaming\npm\yarn.CMD
npm: 6.14.8 - C:\Program Files\nodejs\npm.CMD
Browsers:
Edge: Spartan (44.19041.1266.0), Chromium (97.0.1072.76)
Internet Explorer: 11.0.19041.1202
npmPackages:
@sveltejs/adapter-auto: next => 1.0.0-next.17
@sveltejs/kit: next => 1.0.0-next.260
svelte: ^3.44.0 => 3.46.4
Severity
blocking all usage of SvelteKit
Additional Information
No response
Issue Analytics
- State:
- Created 2 years ago
- Reactions:1
- Comments:10 (4 by maintainers)
Agreed, this has been driving me nuts for days until I finally became sure that it was a bug with Sveltekit and not me just being stupid. To add to the strangeness, you can even change the page props and then call a setTimeout for a large amount of time to set the $session store value and after the $session store value gets set the page props will revert to their previous value. How is this even possible!?
If its any help, this is my minimal reproduction of the bug you can see that the props (
user
in this case) get reset when the $session assignment is made 2 seconds after the post call is resolved.