Search code examples
reactjseslintcreate-react-appreact-proptypes

false positive in prop-types validation


This is my stateless custom component

import React from 'react';
import PropTypes from 'prop-types';
import { Link } from 'react-router-dom';
import './../css/bootstrap.min.css';

const RoundLink = (props) => {

    const handleClick = (e) => {
        if (!props.onClick) {
            return;
        }
        props.onClick(e);
    };

    const withLink = (button) => {
        return (
            <Link to={props.url}>
                {button}
            </Link>
        );
    };

    let button = <button onClick={handleClick} className="esgine-round-button btn btn-default round">{props.children}</button>;
    if (props.url) {
        return withLink(button);
    }
    return button;
};

RoundLink.propTypes = {
    url: PropTypes.string,
    onClick: PropTypes.func,
    children: PropTypes.string.isRequired,
};

export default RoundLink;

with my package.json having

"prop-types": "^15.6.1",
"react": "^16.2.0",

as dependency and, in devDependencies

"devDependencies": {
    "eslint": "^4.18.2",
    "eslint-plugin-react": "^7.7.0"
  }

I am also using react-create-app

"react-scripts": "1.1.0",

NOTE: I know it already comes with eslint, we have to remove it from our dependencies and use the one that comes out of the box (we figured out that late and we have to rollback our addition of eslint)

we haven't configured a rule for prop types in .eslintrc (I have there other configurations) so I assume I am getting the error from the default create-react-app configuration.

In the end, when I run the eslint I get the following error

error 'url' is missing in props validation react/prop-types

which is a nonsense since it is clearly defined.

Am I doing anything wrong?


Solution

  • You are not doing anything wrong. The problem is that every function that returns a JSX component is technically a stateless component.

    Therefore, this is also a component:

    const withLink = (button) => {
        return (
            <Link to={props.url}>
                {button}
            </Link>
        );
    };
    

    It accesses props.url and has no propTypes.

    However, I think this is a bug because the plugin should realize that props are not defined as a parameter here.

    The workaround is simple, just access url outside the function:

    const { url } = props;
    const withLink = (button) => {
        return (
            <Link to={url}>
                {button}
            </Link>
        );
    };
    

    or, make it a proper component:

    const WithLink = ({url, button}) => {
        return (
            <Link to={url}>
                {button}
            </Link>
        );
    }
    WithLink.propTypes = ...