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

jed*_*mao 50 javascript reactjs

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

Ema*_*ade 48

如果你真的想打字检查

  • 组件与元素

  • 类与功能组件

  • DOM与复合元素

你可以尝试这样的事情.

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

function isFunctionComponent(component) {
    return (
        typeof component === 'function' && 
        String(component).includes('return React.createElement')
    ) ? true : false;
}

function isReactComponent(component) {
    return (
        isClassComponent(component) || 
        isFunctionComponent(component)
    ) ? true : false;
}

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';
}
Run Code Online (Sandbox Code Playgroud)

使用

// 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
Run Code Online (Sandbox Code Playgroud)

示例Codepen

  • 我猜isFunctionComponent的情况不再有效.通过检查,我发现了类似这样的函数FnChild(props){return _react2.default.createElement('div',{id:'child-fn'}); }` (4认同)
  • 该帖子似乎缺少任何解释您发布代码的原因以及预期如何使用代码.这使其成为SO标准的低质量答案. (2认同)
  • 拒绝投票,因为您没有提到`String(component).includes('return React.createElement')`在许多情况下都无法使用。 (2认同)

Anv*_*cka 13

ReactComponent.prototype.isReactComponent = {};
Run Code Online (Sandbox Code Playgroud)

/node_modules/react/lib/ReactComponent.js中的33个

使用npm安装.此时,没有可用于检查其有效性的直接方法.你在做什么是正确的.

  • Dan Abramov:“.isReactComponent 是一个 impl 细节,我们保留将来更改它的权利”(https://twitter.com/dan_abramov/status/787739945301635073) (4认同)

Chr*_*ner 11

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

React.isValidElement(Component())
Run Code Online (Sandbox Code Playgroud)

正如@Leonardo所指出的,一些编译器会导致失败:

String(component).includes('return React.createElement')
Run Code Online (Sandbox Code Playgroud)

  • 这感觉更适合作为评论而不是答案。 (4认同)

Jac*_*bec 9

最简单的解决方案是:

React.isValidElement(element)
Run Code Online (Sandbox Code Playgroud)

  • 使用此方法,我在工作的功能性 React 组件上得到“false”:/ (2认同)

Die*_*ego 5

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

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

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

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