Subscribe on changes!

watchEffect should not track watch's callback when the instance is not mounted

avatar
Nov 28th 2021

Version

3.2.23

Reproduction link

stackblitz.com

Steps to reproduce

  1. 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()
}
avatar
Dec 23rd 2021

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?

avatar
Dec 23rd 2021

Because this is a low-priority edge case and we have other higher priority things to work on. Please be patient.