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

Cannot change $:-computed variable when it is computed from props #7574

Closed
tenor-dev opened this issue May 31, 2022 · 3 comments
Closed

Cannot change $:-computed variable when it is computed from props #7574

tenor-dev opened this issue May 31, 2022 · 3 comments
Milestone

Comments

@tenor-dev
Copy link

Describe the bug

$: expression should track source variables and execute only when they change.
This works with local component state, but not when the state is passed to another component.

This is a consistency and developer usability issue. As a developer, I expect exported variables to work exactly the same as internal ones, especially if they are not bound in parent. As a result, a lot of "strange" code needs to be written to workaround the issue.

Reproduction

https://svelte.dev/repl/1d4698e72d614e0e96450b52c33f8665?version=3.48.0

Logs

No response

System Info

Not relevant

Severity

annoyance

@gtm-nayan
Copy link
Contributor

gtm-nayan commented May 31, 2022

Line 125 of the generated code contains ($$invalidate(0, names), $$invalidate(1, hello)), since hello is getting invalidated, it resets names again

Related #7416, #4933

See #7416 (comment)

@tenor-dev
Copy link
Author

tenor-dev commented May 31, 2022

@gtm-nayan it's a known issue then. We stumble upon it from time to time in our projects and it's quite frustrating.
It's also VERY frustrating to Svelte beginners, because it seems illogical until you look at the generated source code. And even then it's hard to understand why compiler does this...

Svelte otherwise has an easy way to explain the reactivity - "if the compiler sees a read, it will re-run the code on change", and "this only happens on some variable assignment". But in this case, there is no obvious reason that hello should be invalidated.

I think this wasn't an issue a while ago when I started using Svelte 3. Do we really need Svelte 4 to fix this obviously bad behavior?

@dummdidumm
Copy link
Member

This comes down to $: standing for two things and it's not easy to distinguish:

  • side effects that happen in reaction to something
  • derived state that keeps values in sync

Svelte 5 fixes this by separating these into two distinct runes, $effect and $derived. That way it's much clearer what's going on and such edge cases are avoided entirely.
In this case, you would have a $state variable and either update that through the binding of from an $effect, resulting in the desired behavior.

Furthermore, due to fine-grained reactivity possibilities in Svelte 5, you can now write the state such that the binding will not update the whole array.

@dummdidumm dummdidumm added this to the 5.x milestone Nov 15, 2023
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

No branches or pull requests

3 participants