简体   繁体   中英

Prop in stateless component fat arrow function cannot be validated with eslint

I have the following:

import React from 'react';
import PropTypes from 'prop-types';

const Foo = (props) => {
  const myFunc = () => (
    <div>
      { props.bar }
    </div>
  );

  return myFunc();
};

Foo.propTypes = {
  bar: PropTypes.string.isRequired,
};

export default Foo;

Eslint tells me:

'bar' is missing in props validation

It seems as though when the fat arrow returns JSX, eslint fails.

I can get around this by assigning bar to this :

const Foo = (props) => {
  this.bar = props.bar; //eslint sees this properly

  const myFunc = () => (
    <div>
      { this.bar }
    </div>
  );

Is this the best way to go about this? Why is this happening?

.eslintrc

// .eslint.json

{
  "extends": "airbnb",
  "parser": "babel-eslint",
  "parserOptions": {
    "ecmaVersion": 2016,
    "sourceType": "module",
    "ecmaFeatures": {
    "jsx": true
    }
  },
  "env": {
    "browser": true,
     "es6": true,
     "jest": true
  },
  "plugins": [
    "react",
    "import",
    "jsx-a11y"
  ],
  "rules": {
        "react/jsx-filename-extension": 0,
        "func-names": 0,
        "strict": 0,
        "quotes": [1, "single"],
        "no-confusing-arrow": 0,
        "react/prefer-es6-class": 0,
        "babel/generator-star-spacing": 0,
        "no-underscore-dangle": 0,
        "linebreak-style": ["error", "windows"],
        "no-named-as-default": 0,
  }
}

I imagine what's happening is myFunc is seen as another stateless component. Just eyeballing your code, it looks valid, but eslint likely is seeing myFunc as needing its own propTypes , even though the props you are accessing is in the same scope. You could verify this by doing something like:

const myFunc = (props) => (
  <div>
    { props.bar }
  </div>
);
myFunc.propTypes = {
  bar: PropTypes.string.isRequired,
};

return myFunc({ bar: props.bar });

But for practical advice on this, I would suggest just returning

<div>
  { props.bar }
</div>

from your Foo instead of creating a closure inside it.

What happens if you do it this way?

import React from 'react';
import PropTypes from 'prop-types';

const Foo = (props) => {
  const myFunc = (bar) => (
    <div>
      { bar }
    </div>
  );

  // access bar here.
  return myFunc(props.bar);
};

Foo.propTypes = {
  bar: PropTypes.string.isRequired,
};

export default Foo;

I have discovered a strange behaviour. The only difference is in the return statement: 在此处输入图片说明 在此处输入图片说明

Now also the bar in propTypes is uncommented: 在此处输入图片说明 在此处输入图片说明

PS: You could also use destructuring to get around the props validation Foo = ({ bar }) => ... instead of having to assign it const bar = props.bar .

I think the problem is because the myFunc looks like a functional component and that eslint is picking it up wrongly.
在此处输入图片说明

Also, this is rather funny, if you simply rename the props to anything else, eslint goes silent :)
在此处输入图片说明

//edit Seems like my reasoning was somewhat correct https://github.com/yannickcr/eslint-plugin-react/issues/2135#issuecomment-455034857

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