-
-
Notifications
You must be signed in to change notification settings - Fork 4.5k
Reactivity does not work for reference values #3197
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 would argue that this is the way reactivity is implemented in most reactive frameworks. At heart is the notion of identity vs. that of value. The reactive frameworks I know mostly avoid being reactive on the value of a reference. If the simple case of an array
So if every changes in the top-level array would result in a reaction from If you want to react on every change (in value) of a variable, then you can associate a change of value to a change in reference -- that is the idea behind immutable data. That way you have the best of both worlds, with a single simple reactive rule. PS: I am not part of the Svelte team, and this is only my humble opinion |
Appreciate the input. Perhaps I didn't communicate the issue well enough. It's not about being reactive on
These lead to the update function being triggered solely because of a test for the The code calling the comparison function,
and could be changed to
but I don't think you'd want to do the comparison if the contents of So maybe...
where |
This is a documented behaviour of Svelte - you need to reassign object and array values in order to trigger reactivity events. |
Related to #2759, #3075
REPLs:
Bind:value example: https://svelte.dev/repl/033f49fa812b48abac0b2fc0096be97c?version=3.6.5
Immutability Example: https://svelte.dev/repl/84bca1af3b1b4aeb8979860bc2c12450?version=3.6.5
Reactivity for reference value variables, arrays and objects, does not work. I detailed why it doesn't in #2759. Basically arrays and objects are reference values; therefore, assigning them to another variable or comparing them only compares their reference and not the value.
This is seen in the comparison function
safe_not_equal
.Both
a
andb
,$$.ctx[key]
and$$.ctx[key] = value
, refer to the same reference value for arrays and objects; therefore,typeof a === 'object'
is always true and themake_dirty
method is executed. So reactivity appears to work, but it really does not.Steps to reproduce:
Immutable example:
wash the car
under immutable. The function has been changed to use id + 1.The second line is selected and the console message shows the change.
mow the lawn
.If the intent is to make the entire array or object reactive when binding to an element in the array or object, then a deep copy and deep compare is going to be required. I attempted to fix this for bind:value, but in running the test suite there were numerous failures. I tried to use JSON.parse(JSON.stringify(object)), but this fails when an element within the object is unknown to the JSON methods. For example in element-ref (hydration), there's an object HTMLHeadingElement which the JSON methods turn to Object. There are utility methods in Lodash for a deep copy and compare, but that would add a runtime dependency to Svelte.
The text was updated successfully, but these errors were encountered: