gloriasoft / veaury

Use React in Vue3 and Vue3 in React, And as perfect as possible!
MIT License
1.27k stars 81 forks source link

[React In Vue] Warning: Invalid value for prop `_` on <li> tag. Either remove it from the element, or pass a string or number value to keep it in the DOM. #115

Closed baijunjie closed 4 months ago

baijunjie commented 5 months ago

这个库太叼了,可以轻松在 Vue 中使用 React 组件!

不过我遇到了一个小问题,研究了一天也没找到解决方案,想请教一下解决方案 🙏🏻

问题描述: 在Vue3中,使用React组件,以下代码一切正常,且运行完美

<script setup lang="ts">
import { applyPureReactInVue } from 'veaury'
import { Card } from '@nextui-org/react'
const VueCard = applyPureReactInVue(Card)
</script>

<template>
  <VueCard>
    Hello, World!
  </VueCard>
</template>

当我添加一个React子组件VueCardBody时,也运行正常

<script setup lang="ts">
import { applyPureReactInVue } from 'veaury'
import { Card, CardBody } from '@nextui-org/react'
const VueCard = applyPureReactInVue(Card)
const VueCardBody = applyPureReactInVue(CardBody)
</script>

<template>
  <VueCard>
    <VueCardBody></VueCardBody>
  </VueCard>
</template>

紧接着问题就来了,当我为React子组件VueCardBody添加一个内容时,console中就会报出警告⚠️

<script setup lang="ts">
import { applyPureReactInVue } from 'veaury'
import { Card, CardBody } from '@nextui-org/react'
const VueCard = applyPureReactInVue(Card)
const VueCardBody = applyPureReactInVue(CardBody)
</script>

<template>
  <VueCard>
    <VueCardBody>Hello, World!</VueCardBody>
  </VueCard>
</template>
image

但内容渲染是正常的,目前来看,貌似也就是一个警告而已,但是很不舒服,于是我尝试着去解决:

<script setup lang="tsx">
import { applyPureReactInVue, getReactNode } from 'veaury'
import { Card, CardBody } from '@nextui-org/react'
const VueCard = applyPureReactInVue(Card)
const VueCardBody = applyPureReactInVue(CardBody)
const Content = () => <div>Hello, World!</div>
</script>

<template>
  <VueCard>
    <VueCardBody :children="getReactNode(Content)"  />
  </VueCard>
</template>

这的确有效,警告消失了,但当我准备更进一步,在内容中使用另一个React组件VueLink时,警告又出现了:

<script setup lang="tsx">
import { applyPureReactInVue, getReactNode } from 'veaury'
import { Card, CardBody, Link } from '@nextui-org/react'
const VueCard = applyPureReactInVue(Card)
const VueCardBody = applyPureReactInVue(CardBody)
const VueLink = applyPureReactInVue(Link)
const Content = () => h(VueLink, () => 'Hello, World!')
</script>

<template>
  <VueCard>
    <VueCardBody :children="getReactNode(Content)" />
  </VueCard>
</template>
image

但这时内容渲染仍然是正常的,于是我只能再次借助 children 属性

<script setup lang="tsx">
import { applyPureReactInVue, getReactNode } from 'veaury'
import { Card, CardBody, Link } from '@nextui-org/react'
const VueCard = applyPureReactInVue(Card)
const VueCardBody = applyPureReactInVue(CardBody)
const VueLink = applyPureReactInVue(Link)
const Content = () => h(VueLink, { children: 'Hello, World!' })
</script>

<template>
  <VueCard>
    <VueCardBody :children="getReactNode(Content)" />
  </VueCard>
</template>

警告终于消失。但是这样开发的话,从子组件开始向下的所有组件都要写成 VNode,并且经过 getReactNode 处理成 ReactNode 才能使用了。

我不清楚其中的原理是什么,貌似从子组件VueCardBody开始,所有的 vue slot 都会发出警告,必须借助 React 的 children 属性才能传递子组件。

请问这是否是一个bug? 或者是预期行为? 有没有更好的解决方案?不胜感谢🙏🏻

devilwjp commented 5 months ago

@baijunjie 警告是正常的,因为veaury内部会使用带有下划线的属性标记在dom节点上,这个警告是来自react,并非是不可解决的问题,但是我的评估是并不紧急,不影响生产环境(build之后不会再出警告)

baijunjie commented 5 months ago

@devilwjp 感谢。由于这个警告量巨大,这可能会导致我忽略掉其他错误,并且在这巨量的警告中debug也是非常头疼的 😭,如果有其他消除警告的方法,请告诉我 🙏🏻

baijunjie commented 5 months ago

终极大法,哈哈

const ignores = [
  'Warning: Invalid value for prop %s on <%s> tag. Either remove it from the element, or pass a string or number value to keep it in the DOM'
]
const _error = console.error
console.error = function (...args) {
  if (ignores.some(ignore => args[0].includes(ignore))) return
  _error(...args)
}
devilwjp commented 4 months ago

@baijunjie 这个问题已经修复,尝试2.3.17