简体   繁体   中英

React eslint error missing in props validation

I have the next code, eslint throw:

react/prop-types onClickOut; is missing in props validation

react/prop-types children; is missing in props validation

propTypes was defined but eslint does not recognize it.

import React, { Component, PropTypes } from 'react';

class IxClickOut extends Component {
  static propTypes = {
    children: PropTypes.any,
    onClickOut: PropTypes.func,
  };

 componentDidMount() {
    document.getElementById('app')
      .addEventListener('click', this.handleClick);
  }

  componentWillUnmount() {
    document.getElementById('app')
      .removeEventListener('click', this.handleClick);
  }

  handleClick = ({ target }: { target: EventTarget }) => {
    if (!this.containerRef.contains(target)) {
      this.props.onClickOut();
    }
  };

  containerRef: HTMLElement;

  render() {
    const { children, ...rest } = this.props;
    const filteredProps = _.omit(rest, 'onClickOut');

    return (
      <div
        {...filteredProps}
        ref={container => {
          this.containerRef = container;
        }}
      >
        {children}
      </div>
    );
  }
}

export default IxClickOut;

package.json

{
  "name": "verinmueblesmeteor",
  "private": true,
  "scripts": {
    "start": "meteor run",
    "ios": "NODE_ENV=developement meteor run ios"
  },
  "dependencies": {
    "fine-uploader": "^5.10.1",
    "foundation-sites": "^6.2.3",
    "install": "^0.8.1",
    "ix-gm-polygon": "^1.0.11",
    "ix-type-building": "^1.4.4",
    "ix-type-offer": "^1.0.10",
    "ix-utils": "^1.3.7",
    "keymirror": "^0.1.1",
    "meteor-node-stubs": "^0.2.3",
    "moment": "^2.13.0",
    "npm": "^3.10.3",
    "rc-slider": "^3.7.3",
    "react": "^15.1.0",
    "react-addons-pure-render-mixin": "^15.1.0",
    "react-dom": "^15.1.0",
    "react-fileupload": "^2.2.0",
    "react-list": "^0.7.18",
    "react-modal": "^1.4.0",
    "react-redux": "^4.4.5",
    "react-router": "^2.6.0",
    "react-styleable": "^2.2.4",
    "react-textarea-autosize": "^4.0.4",
    "redux": "^3.5.2",
    "redux-form": "^5.3.1",
    "redux-thunk": "^2.1.0",
    "rxjs": "^5.0.0-beta.9",
    "rxjs-es": "^5.0.0-beta.9",
    "socket.io": "^1.4.8"
  },
  "devDependencies": {
    "autoprefixer": "^6.3.6",
    "babel-eslint": "^6.0.4",
    "babel-plugin-transform-decorators-legacy": "^1.3.4",
    "babel-preset-es2015": "^6.9.0",
    "babel-preset-react": "^6.5.0",
    "babel-preset-stage-0": "^6.5.0",
    "core-js": "^2.0.0",
    "cssnano": "^3.7.1",
    "eslint": "^2.12.0",
    "eslint-config-airbnb": "^9.0.1",
    "eslint-import-resolver-meteor": "^0.2.3",
    "eslint-plugin-import": "^1.8.1",
    "eslint-plugin-jsx-a11y": "^1.2.2",
    "eslint-plugin-react": "^5.1.1",
    "node-sass": "^3.8.0",
    "postcss-cssnext": "^2.6.0",
    "sasslets-animate": "0.0.4"
  },
  "cssModules": {
    "ignorePaths": [
      "node_modules"
    ],
    "jsClassNamingConvention": {
      "camelCase": true
    },
    "extensions": [
      "scss",
      "sass"
    ],
    "postcssPlugins": {
      "postcss-modules-values": {},
      "postcss-modules-local-by-default": {},
      "postcss-modules-extract-imports": {},
      "postcss-modules-scope": {},
      "autoprefixer": {}
    }
  }
}

.babelrc

{
  "presets": [
    "es2015",
    "react",
    "stage-0"
  ],
  "whitelist": [
      "es7.decorators",
      "es7.classProperties",
      "es7.exportExtensions",
      "es7.comprehensions",
      "es6.modules"
  ],
  "plugins": ["transform-decorators-legacy"]
}

.eslintrc

{
  "parser": "babel-eslint",
  "extends": "airbnb",
  "rules": {
    "no-underscore-dangle": ["error", { "allow": [_id, b_codes_id] }],
  },
  "settings": {
    "import/resolver": "meteor"
  },
  "globals": {
    "_": true,
    "CSSModule": true,
    "Streamy": true,
    "ReactClass": true,
    "SyntheticKeyboardEvent": true,
  }
}

You need to define propTypes as a static getter if you want it inside the class declaration:

static get propTypes() { 
    return { 
        children: PropTypes.any, 
        onClickOut: PropTypes.func 
    }; 
}

If you want to define it as an object, you need to define it outside the class, like this:

IxClickOut.propTypes = {
    children: PropTypes.any,
    onClickOut: PropTypes.func,
};

Also it's better if you import prop types from prop-types , not react , otherwise you'll see warnings in console (as preparation for React 16 ):

import PropTypes from 'prop-types';

I know this answer is ridiculous, but consider just disabling this rule until the bugs are worked out or you've upgraded your tooling:

/* eslint-disable react/prop-types */ // TODO: upgrade to latest eslint tooling

Or disable project-wide in your eslintrc:

"rules": {
  "react/prop-types": "off"
}

It seems that the problem is in eslint-plugin-react .

It can not correctly detect what props were mentioned in propTypes if you have annotated named objects via destructuring anywhere in the class.

There was similar problem in the past

I ran into this issue over the past couple days. Like Omri Aharon said in their answer above, it is important to add definitions for your prop types similar to:

SomeClass.propTypes = {
    someProp: PropTypes.number,
    onTap: PropTypes.func,
};

Don't forget to add the prop definitions outside of your class. I would place it right below/above my class. If you are not sure what your variable type or suffix is for your PropType (ex: PropTypes.number), refer to this npm reference . To Use PropTypes, you must import the package:

import PropTypes from 'prop-types';

If you get the linting error: someProp is not required, but has no corresponding defaultProps declaration all you have to do is either add .isRequired to the end of your prop definition like so:

SomeClass.propTypes = {
    someProp: PropTypes.number.isRequired,
    onTap: PropTypes.func.isRequired,
};

OR add default prop values like so:

SomeClass.defaultProps = {
    someProp: 1
};

If you are anything like me, unexperienced or unfamiliar with reactjs, you may also get this error: Must use destructuring props assignment . To fix this error, define your props before they are used. For example:

const { someProp } = this.props;

对我来说,将eslint-plugin-react升级到最新版本 7.21.5 解决了这个问题

问题出在 handleClick 中的流注释中,我删除了它并且工作正常,谢谢@alik

Issue: 'id1' is missing in props validation, eslintreact/prop-types

<div id={props.id1} >
    ...
</div>

Below solution worked, in a function component:

let { id1 } = props;

<div id={id1} >
    ...
</div>

Hope that helps.

PropTypes checking is a good thing, not recommend to ignore by settings

You can auto generate the propTypes by using vscode React PropTypes Generate extension:

  1. Select your Component's name
  2. Press command + . (Windows is Ctrl + .) show Code Actions and select PropTypesGenerate, or press shift + command + alt + P (Windows is shift + ctrl + alt + P) in the macOS
  3. Input propType to replace default type

I'm finding eslint to be overly strict in the project I'm working on myself but for this error I fixed it by defining my interface and then implementing as such:

interface myInterface: {
  test: string
}

const MyComponent: React.FC<myInterface> = (props: myInterface) => {

Duplicating my answer from a similar question: https://stackoverflow.com/a/69199304/4290193

eslint-plugin-react@^7.25.0 appears to have resolved the issue for those using React.FC<IProps> with react/prop-types validation rule.

So instead of

const Example: React.FC<IProps> = (props: IProps) => ...

This now works without warnings after the update

const Example: React.FC<IProps> = (props) => ...

Functional React component. Defined as object. I got this error because I copied and pasted the object from a different with a slightly different name and forgot to change the name of the proptypes object.

FooterIcons.propTypes = {} -> FooterIcon.propTypes

Install prop-types package with- npm i prop-types --save Import it-

import PropTypes from 'prop-types';

Then specify the props, I implemented this way-

export default function Text({ children }) {
    Text.propTypes = {
        children: PropTypes.node.isRequired,
        };
  return (
    <VStyle className="para">
      <p>{children}</p>
    </VStyle> 
  );
}

Also add this in your eslintrc.json or .js file

"rules": {
    "react/prop-types": "off"
  }

Instead of disable prop-types rule, we can introduce children property as part of component props, eg:

import React, { Component } from 'react';

export default class ErrorBoundary extends Component<{ children: React.ReactNode }> {
  constructor(props: { children: React.ReactNode }) {
    super(props);

    this.state = { error: null, errorInfo: null };
  }

  componentDidCatch(error: Readonly<unknown>, errorInfo: Readonly<unknown>): void {
    this.setState({ error, errorInfo });
  }

  render(): React.ReactElement | React.ReactNode {
    const { children } = this.props;
    const { error, errorInfo } = this.state as Readonly<Record<string, { componentStack: string }>>;

    if (errorInfo)
      return (
        <details>
          <h3>Oops, error detected.</h3>
          <p>{error?.toString()}</p>
          <p>{errorInfo?.componentStack}</p>
        </details>
      );
    return children;
  }
}

Above one is typical example of getting eslint error gone ~~

Don't worry be happy ~~

On the new version of React and also Next.js, you can simply import PropTypes as follows,

Post.defaultProps = {
  posts: "",
};

Post.propTypes = {
  posts: PropTypes.string,
};

export default Post;

Another way is:


File: App.js

    ...
        <Component1 key1="abc" />
    ...

File: Component1.js

1 error :

    function Component1 ({ key1 }) {
        console.log('key1', key1);
    }

2 error :

    function Component1 (props) {
        let{ key1 } = props;
        console.log('key1', key1);
    }

3 works :

NOTE: prop instead of props

    function Component1 (prop) {
        let{ key1 } = prop;
        console.log('key1', key1);
    }

Looks like, linter only checks for proper word props , not for prop or like.
It's a solution if you are just getting started or quick prototyping.
For later or large projects, defining proptypes might be better.


The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM