facebook / prop-types

Runtime type checking for React props and similar objects
MIT License
4.48k stars 356 forks source link

Clarify Usage of elementType #334

Closed gbroques closed 3 years ago

gbroques commented 3 years ago

According to the Usage section in the README, elementType is for a "React element type (ie. MyComponent)".

// A React element type (ie. MyComponent).
optionalElementType: PropTypes.elementType,

However, I can also pass a string corresponding to the name of a DOM element (e.g. "span", "div", etc.) without triggering a prop types warning.

Will elementType validate the string is a valid DOM element, or can I pass "bologna" without triggering a prop types warning?

It's not clear what elementType is validating, and what's allowable from the Usage section alone.

Can we clarify this?


Consider the following example.

JS Fiddle: https://jsfiddle.net/h02ka7up/63/

function Test() {
    return (
        <Typography component="span">Text</Typography>
    );
}

Typography.propTypes = {
  component: PropTypes.elementType,
  children: PropTypes.node,
};

function Typography(props) {
    const Component = props.component || "p";
    return <Component>{props.children}</Component>;
}

ReactDOM.render(
  <Test />,
  document.getElementById('container')
);
ljharb commented 3 years ago

elementType calls into react-is's isValidElementType function, which does not check the contents of the string: https://github.com/facebook/react/blob/master/packages/shared/isValidElementType.js

In other words, a valid element type is:

  1. a string
  2. a function
  3. one of react's special element-like things, like React.Fragment, Suspense, etc
gbroques commented 3 years ago

@ljharb Thank you for clarifying! Would a PR to update the Usage comment to the following be welcomed?

// A React element type (eg. MyComponent).
// a function, string, or "element-like" object (eg. React.Fragment, Suspense, etc.)
// see https://github.com/facebook/react/blob/master/packages/shared/isValidElementType.js
optionalElementType: PropTypes.elementType,
ljharb commented 3 years ago

sure, couldn't hurt.