React propTypes component class?
For anyone using PropTypes >= 15.7.0
a new PropTypes.elementType
was added in this pull request and was released on february 10, 2019.
This prop type supports all components (native components, stateless components, stateful components, forward refs React.forwardRef
, context providers/consumers).
And it throws a warning when is not any of those elements, it also throws a warning when the prop passed is an element (PropTypes.element
) and not a type.
Finally you can use it like any other prop type:
const propTypes = { component: PropTypes.elementType, requiredComponent: PropTypes.elementType.isRequired,};
EDITED: Added React's FancyButton example to codesandbox as well as a custom prop checking function that works with the new React.forwardRef
api in React 16.3. The React.forwardRef
api returns an object with a render
function. I'm using the following custom prop checker to verify this prop type. - Thanks for Ivan Samovar for noticing this need.
FancyButton: function (props, propName, componentName) { if(!props[propName] || typeof(props[propName].render) != 'function') { return new Error(`${propName}.render must be a function!`); }}
You'll want to use . Actually... PropTypes.element
PropType.func
works for both stateless functional components and class components.
I've made a sandbox to prove that this works... Figured this was needed considering I gave you erroneous information at first. Very sorry about that!
Working sandbox example!
Here is the code for the test in case link goes dead:
import React from 'react';import { render } from 'react-dom';import PropTypes from "prop-types";class ClassComponent extends React.Component { render() { return <p>I'm a class component</p> }}const FancyButton = React.forwardRef((props, ref) => ( <button ref={ref} className="FancyButton"> {props.children} </button>));// You can now get a ref directly to the DOM button:const ref = React.createRef();<FancyButton ref={ref}>Click me!</FancyButton>;const FSComponent = () => ( <p>I'm a functional stateless component</p>);const Test = ({ ClassComponent, FSComponent, FancyButton }) => ( <div> <ClassComponent /> <FSComponent /> <FancyButton /> </div>);Test.propTypes = { ClassComponent: PropTypes.func.isRequired, FSComponent: PropTypes.func.isRequired, FancyButton: function (props, propName, componentName) { if(!props[propName] || typeof(props[propName].render) != 'function') { return new Error(`${propName}.render must be a function!`); } },}render(<Test ClassComponent={ ClassComponent } FSComponent={ FSComponent } FancyButton={ FancyButton } />, document.getElementById('root'));