JavaScript Proxy Class with Computed Method
Version
3.2.33
Reproduction link
Steps to reproduce
- Open debugger
- Notice 2 console logs show (expected)
- Click Add Filter button
- Notice the 2 lists in the HTML are updated (expected)
- Notice only 1 console log shows (not expected, should be 2)
What is expected?
After you click the Add Filter button, there should be 2 console logs that show.
What is actually happening?
Only 1 console log shows.
I'm using a set trap in one of my classes, and I ran into a couple of issues (outlined in this SO post). The first issue was that I had to use receiver
instead of target
when calling the method in the set trap... calling target
worked for my JS class, but when I started using it in my Vue component, it didn't work at all. The second issue is that I had to use ref
with a watchEffect
instead of computed
as this bug shows. I'm not sure if the first issue is my own ignorance for set traps, or if it's another bug, but I can create a separate issue if need be.
The watchEffect that uses the computed property doesn't update because the value of the computed property is a non-reactive, plain instance of new MyCollection
. So any changes to do on that object are non-reactive.
So the only reactive dependency is the value of the computed itself, and that value doesn't change - it always the same MyCollection
instance.
Wrapping the return value of the computed in reactive()
makes your code work. However, that's not really a great pattern. computed's return values should be treated as readonly.
Some additional notes: As shown, the issue here is unrelated to the implementation details of MyCollection
- the same would be happening with a plain array/object. However I still want to stress that we strongly recommend to use plain, stateless Javascript objects for reactivity, and keep complex, stateful classes and stuff out of reactivity. You already seem to have learned that this opens a can of worms.
Hey @LinusBorg, thanks for the response. I think I understand... ref
's value will wrap whatever I set in a proxy, so I essentially have a proxy of a proxy when using ref
, but computed
's value will just be whatever is returned (without wrapping), which is the instance of MyCollection
. You're then saying if I used reactive
within computed
, it'd return the proxy of a proxy, which would be the same scenario as ref
.
Okay, I think I was getting tripped up because they both logged as proxy in the console, but because one was a wrapper of a proxy, I didn't understand that. What an embarrassing novice mistake! Thanks for clearing that up and sorry for wasting your time.