Skip to content

Reactive-statement updates are triggered wrong, when using objects in it? [with example repo] #7282

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
QuickMick opened this issue Feb 17, 2022 · 3 comments
Milestone

Comments

@QuickMick
Copy link

QuickMick commented Feb 17, 2022

Describe the bug

i have noticed, that when you have e.g. a textarea in a component and if you also have a $:{}reactive-statement, which uses an object, that is passed to the component, then this is called on every keystroke, even if there is no change on the data.

see this example: https://github.com/QuickMick/svelte-computed-with-object-bug

the $:{} in text-field.svelte should work similar to the one in text-field-with-update-function.svelte and should not be triggered, when there is no change. This behavior has started in svelte v3.2.1 i think. If you downgrade the the svelte versions in the package.json to e.g. v3.0.0, it works fine.
it seems, when you use an object in a reactive-statement, the some observers (?) to the object are create which get triggerd by some events? i don't know...

as you see in the 3rd example the inputText is always cleared because of the empty value of value.s. this update should not happen in my opinion, because data nor data.s was changed - so this somehow gets triggered bei the input-event

this is propably related to my other issue: #7266

Reproduction

checkout this: https://github.com/QuickMick/svelte-computed-with-object-bug
install and try to use the textareas, the 3rd example shows the error - i have tried out different scenarios, all of them work, except when you access the object directly in the reactive-statement. it works, when you have it wrapped to a function.

when you have a look at the console output, you see, that the update of the reactive-statement is done on each keystroke.

Logs

No response

System Info

System:
    OS: Linux 5.10 Manjaro Linux
    CPU: (16) x64 Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz
    Memory: 14.19 GB / 31.27 GB
    Container: Yes
    Shell: 5.1.0 - /bin/bash
  Binaries:
    Node: 16.13.0 - ~/.nvm/versions/node/v16.13.0/bin/node
    npm: 8.1.0 - ~/.nvm/versions/node/v16.13.0/bin/npm
  Browsers:
    Chromium: 90.0.4430.72
    Firefox: 87.0
  npmPackages:
    svelte: 3.2.1 => 3.2.1

Severity

blocking an upgrade

@Prinzhorn
Copy link
Contributor

I think this is a duplicate of #4933 and falls under the same umbrella. In your case a = inputText and b = value.s

@QuickMick
Copy link
Author

QuickMick commented Feb 18, 2022

that seems to be similar, yes. i also thought, that #2444 could be the reason for this behavior, but the code there has changed a lot in the new versions.

but there is one additional thing, i am wondering:
why does the "input" event of the textarea cause to update the reactive block, but just if there is an object used? is it the same issue, or another one?

@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.

@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