Jelajahi Sumber

fix(runtime-vapor): handle null/undefined dynamic template refs without warning (#14502)

edison 1 bulan lalu
induk
melakukan
b7a3356dbf

+ 39 - 0
packages/runtime-vapor/__tests__/dom/templateRef.spec.ts

@@ -81,6 +81,45 @@ describe('api: template ref', () => {
     expect(fooEl.value).toBe(null)
   })
 
+  it('dynamic ref can be null or undefined without warning', async () => {
+    const t0 = template('<div></div>')
+    const el = ref(null)
+    const refKey = ref<any>('foo')
+
+    const { render } = define({
+      setup() {
+        return {
+          foo: el,
+        }
+      },
+      render() {
+        const n0 = t0()
+        const setRef = createTemplateRefSetter()
+        renderEffect(() => {
+          setRef(n0 as Element, refKey.value)
+        })
+        return n0
+      },
+    })
+
+    const { host } = render()
+    expect(el.value).toBe(host.children[0])
+
+    refKey.value = null
+    await nextTick()
+    expect(el.value).toBe(null)
+    expect('Invalid template ref type:').not.toHaveBeenWarned()
+
+    refKey.value = 'foo'
+    await nextTick()
+    expect(el.value).toBe(host.children[0])
+
+    refKey.value = undefined
+    await nextTick()
+    expect(el.value).toBe(null)
+    expect('Invalid template ref type:').not.toHaveBeenWarned()
+  })
+
   it('string ref unmount', async () => {
     const t0 = template('<div></div>')
     const el = ref(null)

+ 3 - 0
packages/runtime-vapor/src/apiTemplateRef.ts

@@ -177,6 +177,9 @@ function setRef(
     }
   }
 
+  // dynamic ref can become null / undefined and should only clear old ref
+  if (ref == null) return ref
+
   if (isFunction(ref)) {
     const invokeRefSetter = (value?: Element | Record<string, any> | null) => {
       callWithErrorHandling(ref, instance, ErrorCodes.FUNCTION_REF, [