How to detect a React component vs. a React element?

前端 未结 7 1939
广开言路
广开言路 2020-12-02 10:04

React.isValidElement tests true for both React components as well as React elements. How would I test, specifically, that an object is a React component? Curren

相关标签:
7条回答
  • 2020-12-02 10:07

    This is an old question, with an old answer.

    If you run into this issue, probably you'll want to check the react-is NPM package page: https://www.npmjs.com/package/react-is

    It's an official React module that takes into account details like ref forwarding, and memo to check for an element type.

    To check if a value is an element type do: ReactIs.isValidElementType(obj)

    0 讨论(0)
  • 2020-12-02 10:14

    The simplest solution is:

    React.isValidElement(element)
    
    0 讨论(0)
  • 2020-12-02 10:14

    In addition to @EmanualJade answer, you can use this to check if a variable is a function component

    React.isValidElement(Component())
    

    As @Leonardo has pointed out, some compilers can cause this to fail:

    String(component).includes('return React.createElement')
    
    0 讨论(0)
  • 2020-12-02 10:23

    If you really want to type check for

    • component vs element

    • class vs functional component

    • DOM vs Composite Element

    You could try something like this.

    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';
    }
    

    USE

    // 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
    

    Example Codepen

    0 讨论(0)
  • 2020-12-02 10:26
    ReactComponent.prototype.isReactComponent = {};
    

    33 of /node_modules/react/lib/ReactComponent.js

    Install using npm. At this point, there is no direct method available to check for its validity. What you are doing is correct.

    0 讨论(0)
  • 2020-12-02 10:27

    class Test extends React.Component {}
    
    console.log(!!Test.prototype.isReactComponent);
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

    0 讨论(0)
提交回复
热议问题