sveltejs / svelte

Cybernetically enhanced web apps
https://svelte.dev
MIT License
78.53k stars 4.12k forks source link

Initialized variables are not updated during SSR, when bound to a child component #6856

Open WaltzingPenguin opened 2 years ago

WaltzingPenguin commented 2 years ago

Describe the bug

Variables that are initialized to a value and passed to a child component are not being updated for SSR.

Reproduction

https://svelte.dev/repl/c3bf2fa592004e21b0ff22a791dc81f5?version=3.44.0 Use two components:

File: _child.svelte

<script>
import Child from './_child.svelte'

let count
count = 0 // Removing this line produces the output expected
</script>

<Child bind:count />
Outside: { count }

File: index.svelte

<script>
export let count
count = 5
</script>

Inside: { count }

During SSR of index.svelte, you would expect the output to read:

Inside: 5
Outside: 5

Actual output is

Inside: 5
Outside: 0

System Info

System:
    OS: Windows 10 10.0.19043
    CPU: (12) x64 AMD Ryzen 5 1600 Six-Core Processor
    Memory: 8.96 GB / 15.95 GB
  Binaries:
    Node: 14.15.5 - C:\Program Files\nodejs\node.EXE
    Yarn: 1.22.10 - ~\AppData\Roaming\npm\yarn.CMD
    npm: 7.20.3 - C:\Program Files\nodejs\npm.CMD
  Browsers:
    Chrome: 94.0.4606.81
    Edge: Spartan (44.19041.1266.0), Chromium (94.0.992.50)
    Internet Explorer: 11.0.19041.1202
  npmPackages:
    svelte: ^3.42.6 => 3.44.0

Severity

annoyance

Conduitry commented 2 years ago

I haven't tried this out, but, looking at the compiled code, it seems quite unlikely that there would be a difference in behavior between count++ and count+=1 in SSR mode. Is this what you're seeing?

If the issue is that this doesn't work at all in either case, this would probably be a 'won't fix' currently, because of the way SSR works.

WaltzingPenguin commented 2 years ago

I haven't tried this out, but, looking at the compiled code, it seems quite unlikely that there would be a difference in behavior between count++ and count+=1 in SSR mode. Is this what you're seeing?

Yes, it looks like I wasn't careful in testing. bind:count in the example is acting the exact same as { count } during SSR. I've updated the examples to reflect that.

Are you sure that is a "won't fix"? The SSR output certainly looks like it is supposed to catch updates.

do {
$$settled = true;
$$rendered = `${validate_component(Child, "Child").$$render(
    $$result,
    { count },
    {
        count: $$value => {
            count = $$value;
            $$settled = false;
        }
    },
    {}
)}
Outside: ${escape(count)}`;
} while (!$$settled);