34

How do I mark a property as having to be a DOM element?

This page says that PropTypes.element is actually a React element, so what's the equivalent for DOM element?

machineghost
  • 28,573
  • 26
  • 128
  • 197
mpen
  • 237,624
  • 230
  • 766
  • 1,119

3 Answers3

40
PropTypes.instanceOf(Element)

Is working for me. You can also add isRequired:

PropTypes.instanceOf(Element).isRequired
Gregory Bolkenstijn
  • 9,055
  • 7
  • 33
  • 38
  • Is there a nodejs equivalent? – Greg Aug 15 '19 at 14:23
  • 1
    You can now use `PropTypes.elementType` as explained here: https://stackoverflow.com/questions/48007326/what-is-the-correct-proptype-for-a-ref-in-react/51127130#51127130 – Pandaiolo Sep 05 '19 at 23:09
  • Expanding this answer to include the difference between how to do it with a div vs an imported component could get you some extra rep, just saying – Erik Grosskurth Feb 20 '20 at 23:21
  • 1
    You should avoid using this if you SSR your app because `Element` will be `undefined` in nodejs. If you strip out your PropTypes from your production build you will be fine there. But even so, you'll throw an error in the development build. – Carl von Buelow Jun 13 '20 at 03:43
7

You can check if the passed property is instance of Element:

The Element interface represents an object of a Document. This interface describes methods and properties common to all kinds of elements. Specific behaviors are described in interfaces which inherit from Element but add additional functionality. For example, the HTMLElement interface is the base interface for HTML elements, while the SVGElement interface is the basis for all SVG elements.

class Some extends React.Component {
  render() {
    return (
      <div> Hello </div>
    );
  }
}

const validateDOMElem = (props, propName, componentName) => {
  if (props[propName] instanceof Element === false) {
    return new Error(
      'Invalid prop `' + propName + '` supplied to' +
      ' `' + componentName + '`. Validation failed.'
    );
  }
}

Some.propTypes = {
  htmlElem: validateDOMElem,
};

const para = document.getElementById('para');

ReactDOM.render(<Some htmlElem={para} />, document.getElementById('app'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.js"></script>

<div id="app"></div>
<p id="para"></p>
Hardy
  • 5,112
  • 2
  • 15
  • 25
6

For example with a list component:

MyList.propTypes = {
  children: PropTypes.instanceOf(<li></li>),
}

Works for me.

rvantonisse
  • 61
  • 1
  • 1
  • 5
    I get warning `Failed prop type: Right-hand side of 'instanceof' is not callable` if I use this, does this not work anymore in 2019? – micnil Sep 07 '19 at 19:26