如何检测 React 组件与 React 元素?

IT技术 javascript reactjs
2021-03-09 13:29:19

React.isValidElement测试对 React 组件和 React 元素都为真。我将如何测试,具体来说,一个对象是一个 React 组件?目前,我正在通过测试来做到这一点typeof obj.type === 'function',但我希望有更好的方法。

6个回答

如果你真的想输入检查

  • 组件与元素

  • 类与功能组件

  • DOM 与复合元素

你可以尝试这样的事情。

function isClassComponent(component) {
    return (
        typeof component === 'function' && 
        !!component.prototype.isReactComponent
    )
}

function isFunctionComponent(component) {
    return (
        typeof component === 'function' && 
        String(component).includes('return React.createElement')
    )
}

function isReactComponent(component) {
    return (
        isClassComponent(component) || 
        isFunctionComponent(component)
    )
}

function isElement(element) {
    return React.isValidElement(element);
}

function isDOMTypeElement(element) {
    return isElement(element) && typeof element.type === 'string';
}

function isCompositeTypeElement(element) {
    return isElement(element) && typeof element.type === 'function';
}

利用

// CLASS BASED COMPONENT
class Foo extends React.Component {
  render(){
      return <h1>Hello</h1>;
  }
}

const foo = <Foo />;

//FUNCTIONAL COMPONENT
function Bar (props) { return <h1>World</h1> }
const bar = <Bar />;

// REACT ELEMENT
const header = <h1>Title</h1>;

// CHECK
isReactComponent(Foo); // true
isClassComponent(Foo); // true
isFunctionComponent(Foo); // false
isElement(Foo); // false

isReactComponent(<Foo />) // false
isElement(<Foo />) // true
isDOMTypeElement(<Foo />) // false
isCompositeTypeElement(<Foo />) // true

isReactComponent(Bar); // true
isClassComponent(Bar); // false
isFunctionComponent(Bar); // true
isElement(Bar); // false

isReactComponent(<Bar />) // false
isElement(<Bar />) // true
isDOMTypeElement(<Bar />) // false
isCompositeTypeElement(<Bar />) // true

isReactComponent(header); // false
isElement(header); // true
isDOMTypeElement(header) // true
isCompositeTypeElement(header) // false

示例代码笔

isFunctionComponent 对于一般用例和编写单元测试是不可靠的。此外,如果我模仿 React 函数组件结构及其实例,这将无法检测到真正的组件。
2021-05-03 13:29:19
我猜 isFunctionComponent 的情况不再有效。通过检查我发现了这样的东西function FnChild(props) { return _react2.default.createElement('div', { id: 'child-fn' }); }
2021-05-10 13:29:19
不错的解决方案。这真有趣。谢谢
2021-05-10 13:29:19
拒绝投票,因为您没有提到这String(component).includes('return React.createElement')在许多情况下都行不通。
2021-05-11 13:29:19
该帖子似乎没有解释您发布代码的原因以及预期如何使用代码。这使其成为 SO 标准的低质量答案。
2021-05-18 13:29:19

最简单的解决方案是:

React.isValidElement(element)
这篇文章发表后已经过去了很长时间。我想这种方法现在不是最终的解决方案。如果现在不起作用,请尝试使用其他建议。
2021-05-05 13:29:19
可能还需要先做一个typeof element === 'function'我试图呈现字符串或 React 组件
2021-05-07 13:29:19
false使用这种方法开发了一个工作的、功能性的 React 组件:/
2021-05-18 13:29:19

除了@EmanualJade 答案之外,您还可以使用它来检查变量是否为 function component

React.isValidElement(Component())

正如@Leonardo 指出的那样,某些编译器可能会导致此失败:

String(component).includes('return React.createElement')
这是一个很好的解决方案。之前检查它是否是一个函数 typeof component === 'function' && !!React.isValidElement(component())
2021-04-21 13:29:19
这感觉更适合作为评论而不是答案。
2021-05-05 13:29:19
ReactComponent.prototype.isReactComponent = {};

33 /node_modules/react/lib/ReactComponent.js

使用 npm 安装。在这一点上,没有可用于检查其有效性的直接方法。你在做什么是正确的。

以上方案均不强求安装nodemodule。它指的是代码中的一行以供更多参考。
2021-04-24 13:29:19
我用过instanceof(),效果很好,只有 10 个字符,而 ReactComponent.js 是一个完整的包。为什么不使用内置的更短的东西呢?
2021-04-25 13:29:19
Dan Abramov:“.isReactComponent 是一个 impl 细节,我们保留在未来更改它的权利”(twitter.com/dan_abramov/status/787739945301635073
2021-05-02 13:29:19

这是一个古老的问题,有一个古老的答案。

如果您遇到此问题,您可能需要查看react-isNPM 包页面:https : //www.npmjs.com/package/react-is

这是一个官方的 React module,它考虑了诸如 ref 转发之类的细节,以及检查元素类型的备忘录。

要检查值是否为元素类型,请执行以下操作: ReactIs.isValidElementType(obj)