Skip to content
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

Expressions inside {#if} blocks sometimes not correctly reactive to $derived properties of ES6 classes? #14846

Open
max-kamps opened this issue Dec 27, 2024 · 4 comments · May be fixed by #14855

Comments

@max-kamps
Copy link

max-kamps commented Dec 27, 2024

Describe the bug

In very specific circumstances (see reproduction playground), expressions inside of #if blocks referring to $derived properties of ES6 classes are not reactive.

Expected behavior: Clicking the "Set to 999" button always changes the "Associated Data" and "Associated Data inside the {#if}" rows to the same value, and changes the status line to green.

Actual behavior: Clicking the "Set to 999" button for the first time only changes the "Associated Data" row, while the "Associated Data inside the {#if}" row does not change and the status line remains red.
Only repeatedly clicking between "Set to null" and "Set to 999" eventually produces the expected result.

Apologies if this is user error, but the conditions for this occurring are so specific I have to believe it's a bug! 😄 Playground code was produced by painstakingly deleting code from my project until only a single file remained. Unfortunately I am not knowledgeable enough about Svelte internals to investigate this any further.

Reproduction

https://svelte.dev/playground/55439f2d8d8b47e386fafadac3b2c3ec?version=5.16.0

Logs

No response

System Info

System:
    OS: Linux 6.12 Arch Linux
    CPU: (16) x64 AMD Ryzen 7 7840U w/ Radeon  780M Graphics
    Memory: 17.45 GB / 30.66 GB
    Container: Yes
    Shell: 5.2.37 - /bin/bash
  Binaries:
    Node: 23.4.0 - ~/.nvm/versions/node/v23.4.0/bin/node
    npm: 10.9.2 - ~/.nvm/versions/node/v23.4.0/bin/npm
  npmPackages:
    rollup: ^4.29.1 => 4.29.1

Severity

annoyance

@Leonidaz
Copy link

very strange, seems like a bug. I wonder if it's only appearing in dev vs production?

@petrmacal
Copy link

Hey @max-kamps, I have tried the code you provided and used $derived.by instead, so I can do some logging, along with the expression return..

The derivation re-evaluation has been triggered once the dependent state changed, that's fine. However, the conditional render did not react on the change.

What I found even more interesting is, that when I added console.log($state.snapshot(this.ownData)) into the derivation evaluator fn, it started working. See:

https://svelte.dev/playground/7ae10316bbaa413eb7a26c2d8a5a10b0?version=5.16.0

@webJose
Copy link
Contributor

webJose commented Dec 28, 2024

This probably relates to all the things I don't understand about Svelte's reactivity internals. My guess is that the value being read when the (future) rune $effect.active() is false makes the runtime set the derivation orphan or similar? Since it gets fixed in subsequent clicking, whatever problem is reset/corrected and the template updates as expected.

@Leonidaz
Copy link

Leonidaz commented Dec 28, 2024

@trueadm

btw, $inspect.trace crashes in this use case if set inside the $derived

Uncaught TypeError: Cannot use 'in' operator to search for 'Symbol($state)' in null

looks like a check for null is needed since typeof null is object:

typeof value === 'object' && STATE_SYMBOL in value ? snapshot(value, true) : value

reproduction

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants