Skip to content

[Svelte 5] Bindings to nested fields are not immediately reactive when the target is a class field. #9661

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
AgarwalPragy opened this issue Nov 26, 2023 · 6 comments

Comments

@AgarwalPragy
Copy link

AgarwalPragy commented Nov 26, 2023

Describe the bug

Bindings for nested fields are reactive when the target is a standalone value, but not immediately reactive when the target is a class field.

Reproduction

REPL

<script>
  let val = $state({x: {y: ''}});
	
  class Value {
    x = $state({y: ''})
  }

  const obj = new Value()
</script>

<div>     reactive: <input bind:value={val.x.y} /> {val.x.y}</div>
<div>semi-reactive: <input bind:value={obj.x.y} /> {obj.x.y}</div>

Note that the 2nd binding is semi-reactive - if you change the value in 2nd input, nothing happens, until you also change the value in the 1st input.

Logs

No response

System Info

N/A

Severity

annoyance

@AgarwalPragy AgarwalPragy changed the title [Svelte 5] Bindings to nested fields are not immediately reactive inside classes [Svelte 5] Bindings to nested fields are not immediately reactive when the target is a class field. Nov 26, 2023
@dummdidumm
Copy link
Member

This works as expected - although the behavior is surprising at first.

The reason why this doesn't work in the class case is that Svelte can't see that x is a $state variable, and as such it doesn't schedule an update of obj.x when obj.x.y changes.

If you put Svelte in immutable mode you'd get the same behavior in both cases

@dummdidumm dummdidumm closed this as not planned Won't fix, can't repro, duplicate, stale Nov 27, 2023
@Rich-Harris
Copy link
Member

(for clarity: we have some thoughts on how to make this behaviour less surprising, but it isn't public yet. bear with us)

@AgarwalPragy
Copy link
Author

AgarwalPragy commented Nov 27, 2023

Fair enough - but combined with the fact that Runes based reactivity doesn't work for nested values outside classes either #9639, it seems to make reactivity significantly less powerful - or am I doing it all wrong?

Basically, you need to use a class if you want effects to work on nested values - but then the bindings stop working.

@Antonio-Bennett
Copy link

@dummdidumm Can I know why svelte doesn’t see that it is a $state variable

@dummdidumm
Copy link
Member

dummdidumm commented Nov 28, 2023

obj.x.y refers to the obj variable. It's a regular class instance for Svelte (it doesn't follow the declaration; imagine this can also live in a separate file, Svelte can't follow that). obj.x.y to JavaScript means "invoke the getter for x set the new value for y". Therefore the variable x which is actually the $state is never set, and as such the UI does not update.

@AgarwalPragy
Copy link
Author

Fixed by #9739

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

4 participants