-
-
Notifications
You must be signed in to change notification settings - Fork 4.5k
Svelte 5: Fine grained reactivity when binding directly to array elements. #9687
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
You bind through the list and the index, which causes the list to be invalidated. $.bind_value(
input,
() => $.get(todos)[0].text,
($$value) => $.mutate(todos, $.get(todos)[0].text = $$value)
); Not sure if this will be changed in the future, but right now you can work around it by separating the item from the list first. let todo0 = $derived(todos[0]);
let todo1 = $derived(todos[1]); <input bind:value={todo0.text} />
<input bind:value={todo1.text} /> This now also will generate a warning on the list:
|
Got it. But for me, it is weird binding on a derived state, since the code below does not work:
|
|
I think that maybe "passing by reference" versus "passing by value" is an explanation for your code. Take a look at this simple example with pure javascript: let array = [{value:3}];
function extraction(){
return array[0];
}
let extracted=extraction();
// HERE, extracted IS A REFERENCE TO {value:3}. NOT A COPY.
// NOW, WHEN WE CHANGE extracted, THE ORIGINAL ARRAY WILL CHANGE.
extracted.value=50;
console.log(array[0].value) // SHOWS 50 I think that you could bind to the derived result, because it is a reference for the object inside the array (and not a copy). As a reference, it is the array element itself that you bind to. Do you agree? |
Well, not quite. It could be possible in theory, but that would introduce a special case for The classic example being: let count = $state(0);
let doubled = $derived(count * 2); You cannot just change What you are suggesting has been suggested before in the form of something like a |
Take a look at this REPL. As you can see in the REPL above, updating the derived state changes the original array too. I understand it as a "way back to the source". It smells like a "passing by reference" instead of "passing by value". In my point of view, the same doesn't happen in the example below because "number" is a primitive and, consequently, "doubled" is not a reference, but a complete new calculation. let count = $state(0);
let doubled = $derived(count * 2); |
It would be nice if we could do directly: <input bind:value={todos[0]}> |
Now that #9739 has been merged, I believe this issue can be closed as it now works the way you want it to. (At least, if I've understood your reproduction correctly). |
Uh oh!
There was an error while loading. Please reload this page.
Describe the bug
I don't know if it is a bug, but when I try to reproduce the fine grained reactivity example for specific array elements (without an each block), it doesn't work.
Reproduction
https://svelte-5-preview.vercel.app/#H4sIAAAAAAAACo2UX2-bMBTFv8qVW2kgZWHlkQESS2iC2sEU6KIpyQN_TGaJAsIm6oT47rMJhKTa0ogHX_v4XP84FjQoJRmmSNs0KA9fMdKQVZZogtifUkzoAWcM8zkt6ioWKzqNK1Iyc5tvWYYZMPzGwIB7ykKGpS0Kw3CL5EFNihyPahpmFMvnTvXcGkXRO6v6D-_gLpKCjvKmEYJ49n1rSW4qzOoq72btZNDpoIfVXm5EZfBq1Pf92aNfzC79nd75RXXuH8YPcNRrPOotQOo1oosOrRh28tdjdvc4TXHMJEkGw4QeMy5yWmR4mhV7qQt282U3FSjdbbTCqyvjxed6Qg7m2gmW3ksAtjVbwrdnb_Y0gUfHtWGxsvgwhxVXAuenE_wC1wtg7a2eHHcB0mxpuQtRBUsbfHvmuXNw3B-81aOzsv1umS_63rMN323ftxa2rOmKOLM_WlDpJC9rBhHJE-0QZjU2mgv0FhRTjyrl-uaHcTN8NqFDszmB44PFsdZWwF_uDGgqkugR8qH9mMdNYdwQxNyzfffTMZDreTR3OIx_959DSLtiAqS79FNW_w3g9PJiV3NHUiCG8dAePTwP11t_nAlIrncCm3adFJIeCQZKRVC2_EfyWiQkJThBGqtq3O7avwAu9tKDBAAA
Logs
No response
System Info
?
Severity
annoyance
The text was updated successfully, but these errors were encountered: