如何检查 Dom 元素或 React 组件

9

在创建高阶组件时,我不确定要包装哪种类型的组件,有时它是另一个React组件,有时它可能是普通的DOM元素,如lia

WrappedComp = myHOC(BaseComponent)

MyHOC将额外的props传递给包装组件,在大多数情况下,这将按预期工作。

但有时候,当BaseComponent是例如li时,它将不接受额外的props,React会抛出警告Unkown Prop Warning,说明DOM元素不接受非标准的dom属性:https://facebook.github.io/react/warnings/unknown-prop.html

那么我该如何检查BaseComponent是否为DOM元素?如果是,则不会将额外的props传递给它。

是否有更好的方法来解决这个问题?


你有检查 console.log(BaseComponent) 的输出吗? - user5734311
为什么需要在每个组件上包装HOC?是否可以将您想要扩展的组件进行包装和导出? - hazardous
1
最简单的检查是查看它是否为“function”,typeof(BaseComponent)==“function”,至于HTML组件,React使用“string”。 - hazardous
1
然而,仅凭这个检查并不能解决问题,因为React会在任何定义了“propTypes”的组件上发出这些警告。 - hazardous
1
相关:https://dev59.com/FVwX5IYBdhLWcg3w8TTM#34406703 - rlemon
显示剩余2条评论
2个回答

10

简短回答:
要检查元素是否是 DOM 元素,请检查其类型是否为 string
要检查元素是否为 React 组件,请检查其类型是否为 function

示例:

  if (typeof BaseComponent.type === 'string') {
    return BaseComponent
  }
  // add props

长答案:
React文档中所定义的那样,类似<li><span>这样的内置组件会导致传递一个字符串'li''span'React.createElement方法中,例如React.createElement("li")
以大写字母开头的类型,如<Foo />,会被编译为React.createElement(Foo),并对应于在JavaScript文件中定义或导入的组件。

因此,React组件的类型是function,而DOM组件的类型是string

下面的WrapperComponent记录每个子元素的child.typetypeof。输出结果是functionstringstring

function WrappedComponent({children}) {
  return React.Children.map(children, child => {
    console.log(typeof child.type)
    ...
  })
}

const BaseComponent = ({children}) => children

function App() {
  return (
    <WrappedComponent>
      <BaseComponent>This element has type of function</BaseComponent>
      <span>This element has type of string</span>
      <li>This element has type of string</li>
    </WrappedComponent>
  )
}

我相信这是正确的答案。 - Faris Marouane

4

检查BaseComponent是否为React组件,并添加所需的props。

if(BaseComponent.prototype.isReactComponent){
    //add props
}

有关此事的任何文档吗? - Leonardo
您可以在源代码中查看它:https://github.com/facebook/react/blob/b1b4a2fb252f26fe10d29ba60d85ff89a85ff3ec/src/isomorphic/modern/class/ReactBaseClasses.js#L33 - rlemon
6
未记录文档的内部函数应该避免使用,因为它们随时可能发生变化。如果使用纯渲染功能,则这种方法无法运行。 - Leonardo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接