watchEffect within `effectScope()` stops working after navigating away from then back to component
Reproduction
Steps to reproduce the bug
- Navigate to the TestView component in the browser
- Click the button, testData count property is incremented
- Navigate away from it (staying in the SPA)
- Navigate back to TestView
Expected behavior
The button should cause testData.count to be incremented, even after re-mounting the component.
Actual behavior
After navigating back to the component clicking the button updates the refresher, but not testData
testStore.js?t=1675088280233:17 Refresher: 0.05272026601141877
testStore.js?t=1675088280233:11 Watch effect running 0.05272026601141877
testStore.js?t=1675088280233:17 Refresher: 0.937791768731258
testStore.js?t=1675088280233:11 Watch effect running 0.937791768731258
# Navigate away
logger.js:197 [Router] BeforeEach /passes
logger.js:197 [Router] AfterEach: /passes
# Then back
logger.js:197 [Router] BeforeEach /test
logger.js:197 [Router] AfterEach: /test
testStore.js?t=1675088280233:17 Refresher: 0.558079237843816
testStore.js?t=1675088280233:17 Refresher: 0.31739197899941574
Trasfered from pinia and updated the reproduction.
This is similar to https://github.com/vuejs/core/issues/7319 but not exactly the same. Use a regular watch()
as a workaround.
I cannot use a regular watch, as I mentioned the sample code above is an inlined version of VueUse:computedAsync.
Here is the original store:
import { defineStore } from "pinia"
import { epClient } from "@/common-services/epClient"
import { recomputedAsync } from "@/common-services/vue-recomputed-async"
import urlcat from "urlcat"
export const useRegisterStore = defineStore("RegisterStore", () => {
function logError(e) {
console.log("ComputedAsync error: " + JSON.stringify(e))
}
const { data: passes, refresh: refreshPasses } =
recomputedAsync(async () => {
return await epClient.get("/register/passes")
}, [], { onError: logError })
const savePass = async (pass) => {
try {
await epClient...
} finally {
refreshPasses()
}
}
The linked issue put me on the right track, calling useXxxStore from main.js before the Vue app is mounted is a valid workaround, watchEffect gets called with currentInstance = null and the effect works normally.
hmm, maybe something after cd7c887b755810aedf83f3d458cb956d5b147f6f broke this then? because it fails on the latest commit on the main branch
@posva duplicate of https://github.com/vuejs/core/issues/7319 it works on the latest version. see