Closed kgrzywacz closed 3 years ago
@kgrzywacz, thanks for the detailed repro. Unfortunately, this use case is not supported, and stated in the documentation; check the last part of the track section :
However, the framework doesn't observe mutations made to complex objects, such as objects inheriting from Object, class instances, Date, Set, or Map.
I'll close this issue as it is working as intended.
@jodarove Thanks for quick reply. I am aware of this limitation and it's not the case in this situation.
Instance of the class Value
is used to store all variables, create a plain javascript object (that is pushed to a tracked array) and later modify this plain object using stored references, it is not tracked.
In the App
class (that extends LightningElement
) you can see that there are fields
values
store array of class instancesvaluesUI
store array of plain javascript objects.
Later when handleSwap
method is run it uses values
array to modify objects which are referenced in valuesUI
array.correct, however, they are not modified from the one in component (valuesUI
, which is a proxy that tracks mutations), they are modified as part of the Value
instance, and the framework can't keep track of those changes.
Hm, my intuition was (since both valuesUI array and Value
instances contain reference to the same object) that no matter through which reference I will modify it, it will be detected since in the end both reference the same place in memory.
How does lwc tracks changes then? Does it check which references were accessed in code?
Ah, that's key. They do not hold the same reference; the track value (valueUI) stores a proxy to the real object (from Value). When you read valueUI
(via the proxy), the engine detects that the view depends on those values, and when you modify it (via the proxy also), the engine is notified that the view is out of date re-render the component. But if you change the object itself, there's no proxy in the middle; therefore, the engine does not detect that the view is out of date, and the component needs to re-render.
You can take a look at @track
fields logic in the installed descriptor. which internally uses the observable-membrane project.
Thanks @jodarove for detailed explanation. Do you think it would make sense to add this information to lwc documentation?
Description
While having an array(with @track annotation) with following structure:
if we change reference of
innerArray
inside the object this change will not be tracked / reflected in the UI.As far as I understand the documentation @track when applied to array or object should detect any changes in inner arrays and objects of tracked element. In this case (check code below) I'm changing the reference of inner array but change isn't reflected in UI.
Steps to Reproduce
See link below.
https://webcomponents.dev/edit/k1QUihllBQdbSYk4m3G9/src/app.js
Expected Results
Value in span should change from
item1
toitem2
.Actual Results
Nothing happens
Browsers Affected
Chrome 95.0.4638.54, Firefox 93.0
Version
Possible Solution
Additional context/Screenshots Add any other context about the problem here. If applicable, add screenshots to help explain.