Skip to content

Changes done by setting store value in context of child component is not propagated back to parent during SSR rendering #8282

@zlepper

Description

@zlepper

Describe the bug

If you have a pair of components, where one is intended to be used in slots of the parent components, and the components communicate by using a store in the context, then updates done to the store by the child component is not propagated back to the parent component during SSR, but only during client side rendering.

Concretely I'm using this to render a semi-dynamic table. When the client is doing the rendering, the table looks like this:
image
However, when done serverside, the output looks like this:
image

Once the client rendering kicks in, the table does update and renders correctly. However, it still causes a bit of a "flash" when things are corrected

One important things to note, the issue only occurs if the location of the child element in the DOM is after the read of the store. If the store is read after the child component has initialized, then the issue does not occur. That trick however cannot be used to solve my table case above, since the child component results in some styling that needs to change on the container element, and thus the child can only run after the parent.

Reproduction

The reproduction here is relatively minimal to keep things simple and illustrate the issue.

Stackblitz: https://stackblitz.com/edit/sveltejs-kit-template-default-wanpgy?file=src/lib/ChildComponent.svelte

The essential components are the ChildComponent and the ParentComponent. The +page.svelte only handles "invoking" the components.

ParentComponent.svelte:

<script>
	import { setContext } from 'svelte';
	import { writable } from 'svelte/store';

  const aStore = writable({value: 'set by parent'});
  setContext('a', aStore);
</script>
Before child component: {$aStore.value}<br>
<slot />
After child component {$aStore.value}

ChildComponent.svelte:

<script>
  import {getContext} from 'svelte';

  const parentStore = getContext('a');
  $parentStore.value = 'Set by child component'
</script>

Logs

No logs here, since this isn't an explicit error.

System Info

npx envinfo --system --binaries --browsers --npmPackages "{svelte,@sveltejs/*,vite}"
success Install finished in 1.534s


  System:
    OS: Linux 5.0 undefined
    CPU: (8) x64 Intel(R) Core(TM) i9-9880H CPU @ 2.30GHz
    Memory: 0 Bytes / 0 Bytes
    Shell: 1.0 - /bin/jsh
  Binaries:
    Node: 16.14.2 - /usr/local/bin/node
    Yarn: 1.22.19 - /usr/local/bin/yarn
    npm: 7.17.0 - /usr/local/bin/npm
  npmPackages:
    @sveltejs/adapter-auto: ^1.0.0 => 1.0.0 
    @sveltejs/kit: ^1.0.0 => 1.0.1 
    svelte: ^3.54.0 => 3.55.0 
    vite: ^4.0.0 => 4.0.3

Severity

serious, but I can work around it

Additional Information

Recording of the issue:
https://user-images.githubusercontent.com/1499810/209962702-1a83deaa-54a1-4439-9517-729bbb9926eb.mp4
You have to watch pretty carefully, since it only flashes the wrong text for a couple of ms.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions