watchEffect should not track watch's callback when the instance is not mounted
Version
3.2.23
Reproduction link
Steps to reproduce
- change the select to key2 options
The select value is still key because the watchEffect has been called.
watchEffect(() => {
console.log('watchEffect');
formData.value = options[0].value;
});
And I find that the formData.value
is track by watchEffect.(I think that is a bug because i don't get the value of formData.value
in watchEffect and it shouldn't be tracked)
So I find the problem in the source code. Here is the code:
// from https://github.com/vuejs/vue-next/blob/20a361541c/packages/runtime-core/src/apiWatch.ts#L353
if (!instance || instance.isMounted) {
queuePreFlushCb(job)
} else {
// with 'pre' option, the first call must happen before
// the component is mounted so it is called synchronously.
job()
}
if the instance is not mounted, watch's callback will be called sync.
So in watchEffect , when I change the value of formData.value
, it will trigger watch's callback sync, and then it will be track the formData
in this effect. I think this is a bug.
Therefore, when first click the option key2 of select, it will still the key option. And when you second click the option key2, It can be change corrently. The watch's callback will call async because the instance has be mounted.
What is expected?
watchEffect should not track watch's callback when the instance is not mounted
What is actually happening?
watchEffect track watch's callback when the instance is not mounted
I think it can be fixed in this way
if (!instance || instance.isMounted) {
queuePreFlushCb(job)
} else {
// with 'pre' option, the first call must happen before
// the component is mounted so it is called synchronously.
pauseTracking()
job()
resetTracking()
}
May I ask when to fix this problem? Is it because my solution still has some problem and you need more time to think about it?