Skip to content

Unexpected Reactive Updates #8895

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

Closed
NfNitLoop opened this issue Jul 3, 2023 · 5 comments
Closed

Unexpected Reactive Updates #8895

NfNitLoop opened this issue Jul 3, 2023 · 5 comments

Comments

@NfNitLoop
Copy link

NfNitLoop commented Jul 3, 2023

Describe the bug

In a component, a reactive update like this:

$: bar = foo.clone()

Ends up causing reactivity to treat foo as updated when it hasn't been changed (and can not have been changed, since it's not passed/bound to any other components.)

Is this a bug, or undocumented behavior?

These kinds of things are difficult to debug and eat a lot of time. There's not good visibility into why Svelte is choosing to act as if some value was updated.

Reproduction

REPL link: https://svelte.dev/repl/65a48991ca7b46218e67b933edca77b4?version=4.0.1

Logs

See logs in the REPL. 😊

System Info

Reproduced in the REPL with v4.0.1, and locally with 3.59.2.

Severity

annoyance

@NfNitLoop
Copy link
Author

reactivity-bug.zip

Just in case there's an issue w/ the reproduction in the REPL, here's the export.

@mpopovic4116
Copy link

Ran into this as well. Seems to be a duplicate of #4933. Undocumented behaviour intended to fix #2444, but causes surprising behaviour in some other cases and was marked as a bug.

Workaround: Hide the dependencies from the compiler. In your REPL's BrokenExample.svelte:11, instead of

$: bar = foo ? foo.clone() : new Example("default bar")

you should do this instead (or make bar a store and use bar.set(...) instead of $bar = ...):

let bar;
function setBar(x) {
    bar = x;
}

$: setBar(foo ? foo.clone() : new Example("default bar"));

That way, the compiler won't know bar depends on foo and won't invalidate both when you modify bar.
This only seems to happen when using two-way bindings or bar = bar (bar = identity(bar) doesn't trigger it).

@NfNitLoop
Copy link
Author

@mpopovic4116 Nice! I'd done something similar in my Workaround.svelte, but it depended on me knowing exactly where foo gets updated. I like that yours still allows for reactivity. Thanks! 👍

And thanks for the issue link. I'd done some searching but didn't find #4933. I think that fully captures this case, so I'll close this as a duplicate and watch the other.

@alexspurling
Copy link

$: bar := foo.clone()

What is the meaning of := here? Does this syntax have a name or is it a typo?

@NfNitLoop

This comment was marked as off-topic.

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