`triggerRef` does not trigger `watch`
undergroundwires opened this issue · 4 comments
Expected behavior
Watching values of manually triggered references should execute the watch callback.
Reproduce
This test fails:
import { nextTick } from 'vue'
test('triggerRef with watch', async () => {
const a = shallowRef(1)
let aTriggered = false
watch(() => a.value, () => {
aTriggered = true
})
triggerRef(a)
await nextTick()
expect(aTriggered).toBe(true)
})More information
Watching the ref itself works fine. According to post by @LinusBorg in vuejs/core#1209 (comment), this is the expected design of Vue.
However, getting value of the ref does not work. So watch(() => a.value, ...) won't work but, watch(a, ...) work. The behavior should be the same and consistent for shallowRefs where state tracking is disabled
watchEffect works fine for these .value calls. This is another undocumented inconsistency with watch.
Official Vue docs state nothing about caching for watch.
As noted in the following comments, the current behavior is expected: vuejs/core#1209 (comment)
@posva OP also opened this issue in the core repo, and there I noted that there is one weird thing: watch(aShallowRef, ...) does trigger the watch. Normal refers, or getter functions, don't. So only when you watch a shallowRef directly, it will be triggered.
This seeems to be by design, but I question the wisdom of that design. See vuejs/core#9579 (comment)
Should we consider re-opening this issue here until we settled the raised question over in core?
Hi, sorry for the duplication, I got confused and opened two issues.
I'd appreciate at least there would be some documentation regarding this. I've updated my application to use watch(aShallowRef to get this working for now.
A trivia: All of the major language models I asked for help including GPT 4.0 is confused about this behavior and expects watch(() => aShallowRef.value) to be triggered, not only humans 🙂
I think having one is core is enough but I think current behavior makes more sense: when you pass a getter, if the returned value do not change, the watcher shouldn’t trigger