Eslint-plugin-react: Prop type object if forbidden [react/forbid-prop-types]

Created on 8 Dec 2018  路  21Comments  路  Source: yannickcr/eslint-plugin-react

Hi I have this component:

import React from 'react';
import PropTypes from 'prop-types';
import { withStyles } from '@material-ui/core/styles';
import Paper from '@material-ui/core/Paper';
import Typography from '@material-ui/core/Typography';

const styles = theme => ({
  root: {
    ...theme.mixins.gutters(),
    paddingTop: theme.spacing.unit * 2,
    paddingBottom: theme.spacing.unit * 2,
  },
});

function PaperSheet(props) {
  const { classes } = props;
  const { title, data } = props;

  return (
    <div>
      <Paper className={classes.root} elevation={1}>
        <Typography variant="h5" component="h3">
          {title}
        </Typography>
        <Typography component="p">
          {data}
        </Typography>
      </Paper>
    </div>
  );
}

PaperSheet.propTypes = {
  classes: PropTypes.object.isRequired,
  title: PropTypes.string.isRequired,
  data: PropTypes.array.isRequired,
};

export default withStyles(styles)(PaperSheet);

````
package.json:
```json
{
  "name": "app",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "start:dev": "webpack && webpack-dev-server"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "@material-ui/core": "^3.6.1",
    "mathjs": "^5.3.1",
    "prop-types": "^15.6.2",
    "react": "^16.7.0-alpha.2",
    "react-dom": "^16.7.0-alpha.2"
  },
  "devDependencies": {
    "@babel/core": "^7.2.0",
    "@babel/preset-env": "^7.2.0",
    "@babel/preset-react": "^7.0.0",
    "babel-eslint": "^10.0.1",
    "babel-loader": "^8.0.4",
    "eslint": "^5.9.0",
    "eslint-config-airbnb": "^17.1.0",
    "eslint-plugin-import": "^2.14.0",
    "eslint-plugin-jsx-a11y": "^6.1.2",
    "eslint-plugin-react": "^7.11.1",
    "webpack": "^4.27.0",
    "webpack-cli": "^3.1.2",
    "webpack-dev-server": "^3.1.10"
  }
}

.eslint.rc

module.exports = {
    "extends": [
        "airbnb",
        "eslint:recommended",
        "plugin:react/recommended"
    ],
    "parser": "babel-eslint",
    "parserOptions": {
        "ecmaFeatures": {
          "jsx": true
        }
      }
};

I got eslint errors for the PropTypes object:

PaperSheet.propTypes = {
  classes: PropTypes.object.isRequired,
  title: PropTypes.string.isRequired,
  data: PropTypes.array.isRequired,
};

The error mentions: Prop type object is forbidden
How can I fix that?

Most helpful comment

You can define as following:
dataOptions: PropTypes.objectOf(PropTypes.object()),

All 21 comments

By using shape or objectOf instead of object. In this case, PropTypes.shape({ root: PropTypes.string.isRequired })

You can define as following:
dataOptions: PropTypes.objectOf(PropTypes.object()),

@EzequielDeSimone-Reflektion the inner one should be a shape tho, not object.

PaperSheet.propTypes = {
  classes: PropTypes.InstanceOf(Array).isRequired,
  title: PropTypes.string.isRequired,
  data: PropTypes.array.isRequired,
};

This is another solution you can solve the issue

Using instanceOf (correction from InstanceOf) is unreliable at best, however. If you want to bypass the spirit of the rule, use an override comment.

You can define as following:
dataOptions: PropTypes.objectOf(PropTypes.object()),

PropTypes.objectOf(PropTypes.object),
PropTypes.object() is not callable.

Given this is the number one Google search result when searching for this eslint error is anyone able to provide an explanation to this rule or a link to an explanation?

The rule is to forbid certain propTypes from being used.

A very common way to configure it is to forbid object and array, because these are very non specific types. Instead, you鈥檇 want to use objectOf and arrayOf, and provide a propType for the contents of the array.

Use this block code:

Index.propTypes = {
  reqData: PropTypes.instanceOf(Object),
};

Most definitely do not; instanceOf is unreliable and should never be used with builtin types.

dataOptions: PropTypes.objectOf(PropTypes.object),

@yogeshepam you鈥檇 still want to avoid using .object there, too.

Easiest way:
PropTypes.shape({}).isRequired

Update (New solution):
PropTypes.oneOfType([PropTypes.object]).isRequired

Simply use this rule

PropTypes.objectOf(PropTypes.any).isRequired

PropTypes.any indicates the values of the object can be of any type.

@josh-wer the point of this rule is that you shouldn't ever use any - use a more descriptive propType.

@josh-wer the point of this rule is that you shouldn't ever use any - use a more descriptive propType.

Okay @ljharb , I get that. Out of curiosity can u explain how that solution is different from PropTypes.objectOf(PropTypes.object) or PropTypes.oneOfType([PropTypes.object]).isRequired suggested by other answers based on the condition you gave. Assuming the prop value is of the shape

{
  name: "John Doe",
  age: 28,
  isAdmin: false
}

In that case, the best is to use shape - but object is still better than any, which allows non object values.

You can define as following:
dataOptions: PropTypes.objectOf(PropTypes.object()),

PropTypes.objectOf(PropTypes.object),
PropTypes.object() is not callable.

chrome warning as follow:
Warning: Failed prop type: Invalid prop children.$$typeof of type symbol supplied to App, expected object.

That means you鈥檙e passing something React creates instead of a normal javascript object.

I'm making a log component that can accept any arbitrary json value. What would be the best approach? Should I just disable this rule for this case?

Yes.

Was this page helpful?
0 / 5 - 0 ratings