eslint-plugin-react: no-unused-prop-types sometimes fails to detect props in functions on stateless components

Here is a minimal example that triggers this:

const PagingBlock = function(props) {
  return (
    <span>
      <a onClick={() => props.previousPage()}/>
      <a onClick={() => props.nextPage()}/>
    </span>
 );
};

PagingBlock.propTypes = {
  nextPage: React.PropTypes.func.isRequired,
  previousPage: React.PropTypes.func.isRequired,
};

The error message is:

  18:17  error  'previousPage' PropType is defined but prop is never used  react/no-unused-prop-types

Notes:

  • Converting this to a React.createClass with static propTypes fixes the issue
  • Removing either <a/> tag produces the correct lint error, the false error only occurs when both are present
  • The error is notified for the first tag (switching nextPage and previousPage inside the render function will make the error text say nextPage is defined but not used

About this issue

  • Original URL
  • State: closed
  • Created 8 years ago
  • Reactions: 36
  • Comments: 33 (11 by maintainers)

Commits related to this issue

Most upvoted comments

this bug also triggers when use ...props.

const PagingBlock = function(props) {
  return (
    <SomeChild {...props} />
 );
};

PagingBlock.propTypes = {
  nextPage: React.PropTypes.func.isRequired,
  previousPage: React.PropTypes.func.isRequired,
};

The error message is the same.

I think we should count all properties as used in this case.

I might do something wrong but this shows onItemClick propType not to be used:

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

import './List.css';

function List(props) {
  return (
    <div className="List">
        I am a list
        {
          props.items.map(item =>
            (<div className="List-item">
              <button onClick={() => props.onItemClick(item.id)}>{item.title} {item.isAdded}
              </button>
            </div>),
          )
        }
    </div>
  );
}

List.propTypes = {
  items: PropTypes.arrayOf(
    PropTypes.shape({
      id: PropTypes.number,
      title: PropTypes.string,
    }),
  ),
  onItemClick: PropTypes.func,
};
List.defaultProps = {
  items: [],
  onItemClick: null,
};
export default List;

Yeah, for me usage of a prop only in componentWillReceiveProps also throws this linting error.

I have a similar problem with PropTypes.shape.

MyComponent.propTypes = {
  error: PropTypes.shape({
    username: PropTypes.string,
    password: PropTypes.string,
  }),
}

And I pass error to the child component as a whole.
<MyChildComponent error={this.props.error} />

ESLint throws

error  'error.username' PropType is defined but prop is never used  react/no-unused-prop-types
error  'error.password' PropType is defined but prop is never used  react/no-unused-prop-types

@healqq looks legit. I’d recommend opening a new issue

export default class Users extends Component {

  static propTypes = {
    ...
    onLoad: PropTypes.func.isRequired,
  };

  async componentWillMount() {
    await Promise.all([
      this.props.onLoad(),
      this.onSearch(),
    ]);
    ...
  }

  ...

}

'onLoad' PropType is defined but prop is never used (react/no-unused-prop-types)

@iegik & @ahauser31 -

I ran into the same issue and found that if you destructure nextProps instead of using dot notation, the linting error is not thrown.

I also confirmed in this thread: https://github.com/yannickcr/eslint-plugin-react/issues/884#issuecomment-253903073

I have the same error too with eslint-plugin-react v^7.19.0

Still throws error when:

static propTypes = {
    data: React.PropTypes.arrayOf(React.PropTypes.any).isRequired,
};

static defaultProps = {
    data: [],
};

componentWillReceiveProps(nextProps) {
    this.state.data = nextProps.data; // Here ESLint do not see usage of data prop
}

@ljharb I’m sorry, pal, my bad. I’ve just mixed up this issue with another, which looks almost the same.

Experiencing the same issue too. Giving me an error saying ‘PropType is defined but prop is never used’ when my props is being used within a function inside a functional component.

Using eslint-plugin-react v^7.14.3 still throw this error

Also failing to detect props being used on react lifecycle functions like

...
modalClosed: PropTypes.bool.isRequired
componentWillReceiveProps(nextProps) {
    if (nextProps.modalClosed) {
      this.props.router.goBack()
    }
  }

Still getting this in the most recent version of eslint-plugin-react in exactly the same code situation as the original example.