fix(suspense): fix nested async child toggle inside already resovled suspense
fix #2215
This commit is contained in:
parent
426a6c996e
commit
cf7f1dbc9b
@ -1093,4 +1093,36 @@ describe('Suspense', () => {
|
|||||||
await nextTick()
|
await nextTick()
|
||||||
expect(root.innerHTML).toBe(`<div><span>2</span></div>`)
|
expect(root.innerHTML).toBe(`<div><span>2</span></div>`)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// #2215
|
||||||
|
test('toggling nested async setup component inside already resolved suspense', async () => {
|
||||||
|
const toggle = ref(false)
|
||||||
|
const Child = {
|
||||||
|
async setup() {
|
||||||
|
return () => h('div', 'child')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const Parent = () => h('div', ['parent', toggle.value ? h(Child) : null])
|
||||||
|
const Comp = {
|
||||||
|
setup() {
|
||||||
|
return () => h(Suspense, () => h(Parent))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const root = nodeOps.createElement('div')
|
||||||
|
render(h(Comp), root)
|
||||||
|
expect(serializeInner(root)).toBe(`<div>parent<!----></div>`)
|
||||||
|
|
||||||
|
toggle.value = true
|
||||||
|
// wait for flush
|
||||||
|
await nextTick()
|
||||||
|
// wait for child async setup resolve
|
||||||
|
await nextTick()
|
||||||
|
// child should be rendered now instead of stuck in limbo
|
||||||
|
expect(serializeInner(root)).toBe(`<div>parent<div>child</div></div>`)
|
||||||
|
|
||||||
|
toggle.value = false
|
||||||
|
await nextTick()
|
||||||
|
expect(serializeInner(root)).toBe(`<div>parent<!----></div>`)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
@ -542,12 +542,11 @@ function createSuspenseBoundary(
|
|||||||
},
|
},
|
||||||
|
|
||||||
registerDep(instance, setupRenderEffect) {
|
registerDep(instance, setupRenderEffect) {
|
||||||
if (!suspense.pendingBranch) {
|
const isInPendingSuspense = !!suspense.pendingBranch
|
||||||
return
|
if (isInPendingSuspense) {
|
||||||
}
|
|
||||||
|
|
||||||
const hydratedEl = instance.vnode.el
|
|
||||||
suspense.deps++
|
suspense.deps++
|
||||||
|
}
|
||||||
|
const hydratedEl = instance.vnode.el
|
||||||
instance
|
instance
|
||||||
.asyncDep!.catch(err => {
|
.asyncDep!.catch(err => {
|
||||||
handleError(err, instance, ErrorCodes.SETUP_FUNCTION)
|
handleError(err, instance, ErrorCodes.SETUP_FUNCTION)
|
||||||
@ -562,7 +561,6 @@ function createSuspenseBoundary(
|
|||||||
) {
|
) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
suspense.deps--
|
|
||||||
// retry from this component
|
// retry from this component
|
||||||
instance.asyncResolved = true
|
instance.asyncResolved = true
|
||||||
const { vnode } = instance
|
const { vnode } = instance
|
||||||
@ -597,7 +595,8 @@ function createSuspenseBoundary(
|
|||||||
if (__DEV__) {
|
if (__DEV__) {
|
||||||
popWarningContext()
|
popWarningContext()
|
||||||
}
|
}
|
||||||
if (suspense.deps === 0) {
|
// only decrease deps count if suspense is not already resolved
|
||||||
|
if (isInPendingSuspense && --suspense.deps === 0) {
|
||||||
suspense.resolve()
|
suspense.resolve()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
Loading…
Reference in New Issue
Block a user