Skip to content

Commit

Permalink
fix(ssr): watchEffect onInvalidate runner initialization
Browse files Browse the repository at this point in the history
  • Loading branch information
tjk committed Feb 27, 2021
1 parent 1dedc19 commit 76fcde1
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 6 deletions.
23 changes: 23 additions & 0 deletions packages/runtime-core/__tests__/apiWatch.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
ComponentInternalInstance,
ComponentPublicInstance
} from '../src/index'
import { setupComponent } from '../src/component'
import {
render,
nodeOps,
Expand Down Expand Up @@ -44,6 +45,28 @@ describe('api: watch', () => {
expect(dummy).toBe(1)
})

// https://github.com/vuejs/vue-next/issues/3322
it('effect onInvalidate succeeds in ssr context', done => {
// XXX do this without double setup and generally less hackily!
let instance: ComponentInternalInstance | null
const noop = () => {}
const Comp = defineComponent({
setup() {
if (!instance) {
instance = getCurrentInstance()
} else {
watchEffect(onInvalidate => {
expect(() => onInvalidate(noop)).not.toThrow(ReferenceError)
done()
})
}
},
render: noop
})
createApp(Comp).mount(nodeOps.createElement('div'))
setupComponent(instance!, true)
})

it('watching single source: getter', async () => {
const state = reactive({ count: 0 })
let dummy
Expand Down
19 changes: 13 additions & 6 deletions packages/runtime-core/src/apiWatch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ import {
Ref,
ComputedRef,
ReactiveEffectOptions,
isReactive
isReactive,
ReactiveEffect
} from '@vue/reactivity'
import { SchedulerJob, queuePreFlushCb } from './scheduler'
import {
Expand Down Expand Up @@ -167,6 +168,7 @@ function doWatch(

let getter: () => any
let forceTrigger = false
let runner: ReactiveEffect<any> | undefined
if (isRef(source)) {
getter = () => (source as Ref).value
forceTrigger = !!(source as Ref)._shallow
Expand Down Expand Up @@ -224,6 +226,9 @@ function doWatch(

let cleanup: () => void
const onInvalidate: InvalidateCbRegistrator = (fn: () => void) => {
if (!runner) {
return
}
cleanup = runner.options.onStop = () => {
callWithErrorHandling(fn, instance, ErrorCodes.WATCH_CLEANUP)
}
Expand All @@ -246,7 +251,7 @@ function doWatch(

let oldValue = isArray(source) ? [] : INITIAL_WATCHER_VALUE
const job: SchedulerJob = () => {
if (!runner.active) {
if (!runner || !runner.active) {
return
}
if (cb) {
Expand Down Expand Up @@ -293,7 +298,7 @@ function doWatch(
}
}

const runner = effect(getter, {
runner = effect(getter, {
lazy: true,
onTrack,
onTrigger,
Expand All @@ -316,9 +321,11 @@ function doWatch(
}

return () => {
stop(runner)
if (instance) {
remove(instance.effects!, runner)
if (runner) {
stop(runner)
if (instance) {
remove(instance.effects!, runner)
}
}
}
}
Expand Down

0 comments on commit 76fcde1

Please sign in to comment.