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

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? Currently, I'm doing it by testing typeof obj.type === 'function', but I'm hoping there's a better way.

81466 次浏览
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.

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

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')

If you want to know what class you have for a particular instance of an object variable, then what you want is the instanceof operator...

function isHTMLElement(obj) {
return (obj instanceof HTMLElement);
}

I tested with both document.createElement('div') (returns true) and <someReactJSComponent /> (returns false).

instanceof is a powerful and useful tool in JavaScript. Check out the official MDN documentation for it: Mozilla Documentation Network: instanceof

"The instanceof operator tests the presence of constructor.prototype in object's prototype chain."

In addition, I have uploaded a code sample with a code-sandbox online to demonstrate the above principle...

Online Code Sandbox :

https://codesandbox.io/s/kmxjq27ol5

Code :

function App() { return (//insert JSX here//);};
const app = App();
const ele = document.createElement("div");
const rootElement = document.getElementById("root");
ReactDOM.render(app, rootElement);
console.log(
"Hello!  Is a React Component HTML???" +
(app instanceof HTMLElement) +
"|  Is an HTML element HTML???" +
(ele instanceof HTMLElement) +
"|"
);

Code Results :

Hello!  Is a React Element HTML???false|  Is an HTML element HTML???true|

No problem (tested Chrome and FF). Just use instanceof.

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>

The simplest solution is:

React.isValidElement(element)

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)