-
-
Notifications
You must be signed in to change notification settings - Fork 4.5k
[Runes] Allow for fine-grained reactivity in array of primitives and leave data structure intact #9249
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
Comments
I also noticed that issue when trying to port an existing piece of code where a single value was wrapped in a store (#9252). With runes I could not just do |
I've found that changing the example with the proxy works when you update the each to the following: <form>
{#each form.values.roles as role, i}
{form.values.roles[i]}
<input bind:value={role} />
{/each}
</form> I also found that when you have 2 each loops that reference the same array like below then the bind will not update correctly unless you change the bind to form.values.roles[i]. FROM: <form>
{#each form.values.roles as role}
<input bind:value={role} />
{/each}
</form> <form>
{#each form.values.roles as role}
<input bind:value={role} />
{/each}
</form> TO: <form>
{#each form.values.roles as role}
<input bind:value={form.values.roles[i]} />
{/each}
</form> <form>
{#each form.values.roles as role}
<input bind:value={form.values.roles[i]} />
{/each}
</form> Interestingly, the bind to form.values.roles[i] does not invalidate the entire array when the value changes and still only causes the $effect to run when the index you are listening to has changed. |
Seems related to this issue: reactivity is lost on #each variables. |
This now works out of the box with |
Uh oh!
There was an error while loading. Please reload this page.
Describe the problem
From my tests with Svelte 5 runes I have not discovered a way to add fine-grained reactivity to arrays that consist entirely of primitives like string, number or boolean.
Suppose I want to make a re-usable createForm function that allows for fine-grained reactivity, for the purpose of this example I will be keeping the code simple
This example above works like a dream and we have no issues. We could even take the example further and create as many nested objects in here as we need with custom setters and getters. What I'd also like to highlight here is that the use of runes has been completely abstracted from the consumer of the method.
Now let's first take a look at how to create a from with array values that works with fine-grained reactivity
We can see from the working example above that the values inside of the roles array had to be wrapped in an object before we can get some fine-rained reactivity, hence the fact that we need to reference .value inside of the each loop. What I'd also like to mention here is that both the effect and the {role.value} just before the input are updating every time the value of a role is changed (This will become more relevant with the example below using proxies).
Describe the proposed solution
I would like to have this fine grained reactivity on an array of primitives without needing to wrap each value in an object so that I can hide the use of runes from the consumer of the method. I can also see this pattern of wrapping everything in an object becoming quite annoying when working with large objects that contain multiple arrays of primitives and need to be sent back and forth between an API. We would have to constantly remember to undo the effects of using runes which added an extra 'value' prop in this case that we need to remove first.
On top of that I think the idea that you need to wrap all your arrays of primitives in an object is quite an unintuitive way of doing things. It will make the argument for adopting Svelte at my current job way more difficult if I have to tell my colleagues that they need to remember that their arrays of primitives are always being converted to arrays of objects.
What makes this even worse is that each library doing some 'runifying' in the background may do so very differently from another library and so they may not even share the same implementation of 'runifying' their arrays of primitives. One library maintainer may choose to use a prop called 'value' while another maintainer may choose to use a prop called 'val' or anything else.
Alternatives considered
I have tried the following as a workaround to address the issue of wrapping primitives in runes using a Proxy.
This works and gives us the fine grained reactivity but with a caveat. The $effect will always run when the input value is changed but the {role} that is placed just before the input in the each loop does not update when it's corresponding input is changed. What this tells me is that the get() inside the proxy is not working correctly but the set() inside the proxy is working as intended.
Importance
would make my life easier
The text was updated successfully, but these errors were encountered: