React PropTypes DOM element?
Asked Answered
A

4

41

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?

Apivorous answered 8/9, 2016 at 23:37 Comment(7)
Do you mean type of DOM element? Checking for a specific type could be done with a custom prop checker against someNode.constructor.name.Foreordain
@MatthewHerbst No, I mean any DOM element. div, span, input, whatever.Apivorous
React.PropTypes.node?Mollusc
div, span, input are also react elements. They get translated to DOM elements only later.Gentry
@Gentry Even if they're fetched with document.getElementById or created with document.createElement and not React.createElement("input")?Apivorous
@Mollusc node is too loose. It includes numbers, strings and arrays.Apivorous
React.PropTypes.node logs a warning Failed prop type: Invalid propElectrometer
T
52
PropTypes.instanceOf(Element)

Is working for me. You can also add isRequired:

PropTypes.instanceOf(Element).isRequired
Thanks answered 21/6, 2018 at 11:8 Comment(6)
Is there a nodejs equivalent?Blindheim
You can now use PropTypes.elementType as explained here: #48007826Rollmop
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 sayingPufahl
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.Tragedy
@Rollmop PropTypes.elementType is NOT for native DOM element instances. See here: github.com/facebook/prop-types/issues/334 and here: github.com/facebook/prop-types/pull/211Abagael
@Abagael thanks for pointing that. This comment is from 2019 and cannot be edited, however, my answer that I mention was updated around that time, as per my comment to svnn that you also reacted to. Let me know if you see any obsolete content left.Rollmop
M
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>
Masto answered 9/9, 2016 at 5:57 Comment(1)
It is also possible not to create a custom validator and use PropTypes.instanceOf(Element)Curiosity
G
6

For example with a list component:

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

Works for me.

Guardian answered 25/4, 2017 at 13:42 Comment(1)
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?Oppressive
L
5

PropTypes.instanceOf(Element) will not work for server-side render, because of ReferenceError: Element is not defined

Suggest using PropTypes.object instead

Lorindalorine answered 22/9, 2021 at 11:22 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.