arrow-left

All pages
gitbookPowered by GitBook
1 of 5

Loading...

Loading...

Loading...

Loading...

Loading...

Don't Call PropTypes Warning

Note:

React.PropTypes has moved into a different package since React v15.5. Please use the prop-types library insteadarrow-up-right.

We provide a codemod script to automate the conversion.

In a future major release of React, the code that implements PropType validation functions will be stripped in production. Once this happens, any code that calls these functions manually (that isn't stripped in production) will throw an error.

hashtag
Declaring PropTypes is still fine

The normal usage of PropTypes is still supported:

Nothing changes here.

hashtag
Don’t call PropTypes directly

Using PropTypes in any other way than annotating React components with them is no longer supported:

If you depend on using PropTypes like this, we encourage you to use or create a fork of PropTypes (such as packages).

If you don't fix the warning, this code will crash in production with React 16.

hashtag
If you don't call PropTypes directly but still get the warning

Inspect the stack trace produced by the warning. You will find the component definition responsible for the PropTypes direct call. Most likely, the issue is due to third-party PropTypes that wrap React’s PropTypes, for example:

In this case, ThirdPartyPropTypes.deprecated is a wrapper calling PropTypes.bool. This pattern by itself is fine, but triggers a false positive because React thinks you are calling PropTypes directly. The next section explains how to fix this problem for a library implementing something like ThirdPartyPropTypes. If it's not a library you wrote, you can file an issue against it.

hashtag
Fixing the false positive in third party PropTypes

If you are an author of a third party PropTypes library and you let consumers wrap existing React PropTypes, they might start seeing this warning coming from your library. This happens because React doesn't see a "secret" last argument that to detect manual PropTypes calls.

Here is how to fix it. We will use deprecated from as an example. The current implementation only passes down the props, propName, and componentName arguments:

In order to fix the false positive, make sure you pass all arguments down to the wrapped PropType. This is easy to do with the ES6 ...rest notation:

This will silence the warning.

thesearrow-up-right
twoarrow-up-right
it passesarrow-up-right
react-bootstrap/react-prop-typesarrow-up-right
Button.propTypes = {
  highlighted: PropTypes.bool,
};
var apiShape = PropTypes.shape({
  body: PropTypes.object,
  statusCode: PropTypes.number.isRequired,
}).isRequired;

// Not supported!
var error = apiShape(json, "response");
Button.propTypes = {
  highlighted: ThirdPartyPropTypes.deprecated(
    PropTypes.bool,
    "Use `active` prop instead"
  ),
};
export default function deprecated(propType, explanation) {
  return function validate(props, propName, componentName) {
    if (props[propName] != null) {
      const message = `"${propName}" property of "${componentName}" has been deprecated.\n${explanation}`;
      if (!warned[message]) {
        warning(false, message);
        warned[message] = true;
      }
    }

    return propType(props, propName, componentName);
  };
}
export default function deprecated(propType, explanation) {
  return function validate(props, propName, componentName, ...rest) {
    // Note ...rest here
    if (props[propName] != null) {
      const message = `"${propName}" property of "${componentName}" has been deprecated.\n${explanation}`;
      if (!warned[message]) {
        warning(false, message);
        warned[message] = true;
      }
    }

    return propType(props, propName, componentName, ...rest); // and here
  };
}

Unknown Prop Warning

The unknown-prop warning will fire if you attempt to render a DOM element with a prop that is not recognized by React as a legal DOM attribute/property. You should ensure that your DOM elements do not have spurious props floating around.

There are a couple of likely reasons this warning could be appearing:

  1. Are you using {...this.props} or cloneElement(element, this.props)? Your component is transferring its own props directly to a child element (eg. transferring props). When transferring props to a child component, you should ensure that you are not accidentally forwarding props that were intended to be interpreted by the parent component.

  2. You are using a non-standard DOM attribute on a native DOM node, perhaps to represent custom data. If you are trying to attach custom data to a standard DOM element, consider using a custom data attribute as described .

  3. React does not yet recognize the attribute you specified. This will likely be fixed in a future version of React. However, React currently strips all unknown attributes, so specifying them in your React app will not cause them to be rendered.

  4. You are using a React component without an upper case. React interprets it as a DOM tag because React JSX transform uses the upper vs. lower case convention to distinguish between user-defined components and DOM tags.


To fix this, composite components should "consume" any prop that is intended for the composite component and not intended for the child component. Example:

Bad: Unexpected layout prop is forwarded to the div tag.

Good: The spread syntax can be used to pull variables off props, and put the remaining props into a variable.

Good: You can also assign the props to a new object and delete the keys that you're using from the new object. Be sure not to delete the props from the original this.props object, since that object should be considered immutable.

React Element Factories and JSX Warning

You probably came here because your code is calling your component as a plain function call. This is now deprecated:

var MyComponent = require("MyComponent");

function render() {
  return MyComponent({ foo: "bar" }); // WARNING
}

hashtag
JSX

React components can no longer be called directly like this. Instead you can use JSX.

hashtag
Without JSX

If you don't want to, or can't use JSX, then you'll need to wrap your component in a factory before calling it:

This is an easy upgrade path if you have a lot of existing function calls.

hashtag
Dynamic components without JSX

If you get a component class from a dynamic source, then it might be unnecessary to create a factory that you immediately invoke. Instead you can just create your element inline:

hashtag
In Depth

var React = require("react");
var MyComponent = require("MyComponent");

function render() {
  return <MyComponent foo="bar" />;
}
function MyDiv(props) {
  if (props.layout === "horizontal") {
    // BAD! Because you know for sure "layout" is not a prop that <div> understands.
    return <div {...props} style={getHorizontalStyle()} />;
  } else {
    // BAD! Because you know for sure "layout" is not a prop that <div> understands.
    return <div {...props} style={getVerticalStyle()} />;
  }
}
on MDNarrow-up-right
var React = require("react");
var MyComponent = React.createFactory(require("MyComponent"));

function render() {
  return MyComponent({ foo: "bar" });
}
Read more about WHY we're making this change.arrow-up-right
function MyDiv(props) {
  const { layout, ...rest } = props;
  if (layout === "horizontal") {
    return <div {...rest} style={getHorizontalStyle()} />;
  } else {
    return <div {...rest} style={getVerticalStyle()} />;
  }
}
function MyDiv(props) {
  const divProps = Object.assign({}, props);
  delete divProps.layout;

  if (props.layout === "horizontal") {
    return <div {...divProps} style={getHorizontalStyle()} />;
  } else {
    return <div {...divProps} style={getVerticalStyle()} />;
  }
}
var React = require("react");

function render(MyComponent) {
  return React.createElement(MyComponent, { foo: "bar" });
}

Warnings

Special Props Warning

Most props on a JSX element are passed on to the component, however, there are two special props (ref and key) which are used by React, and are thus not forwarded to the component.

For instance, attempting to access this.props.key from a component (i.e., the render function or propTypes) is not defined. If you need to access the same value within the child component, you should pass it as a different prop (ex: <ListItemWrapper key={result.id} id={result.id} />). While this may seem redundant, it's important to separate app logic from reconciling hints.