eslint-plugin-react: no-unused-prop-types false positives
The no-unused-prop-types rule reports false positives for me.
Here’s my code:
import React from 'react';
import Buddy from './Buddy';
import Spinner from './Spinner';
import BuddyBox from './BuddyBox';
import '../css/buddies.css';
export default function Buddies(props) {
let buddies = props.activityBuddies.map(item => (
<BuddyBox key={item.id} {...item} endFriendship={props.endFriendship} />
));
if (buddies.length === 0) {
buddies = <Spinner />;
}
return (
<div className="buddies">
<div className="buddies--content">
{buddies}
</div>
<div className="buddies--sidebar">
<div className="buddies--add">
{props.friendrequests && props.friendrequests.map(item => (
<div key={item.id}>
<Buddy
name={item.username}
profilePicture={item._links.image.href}
timestamp={item.last_sign_in_at}
/>
<button
className="buddies--confirm-button"
onClick={() => {
props.handleFriendrequest(item._links.confirm.href);
}}
>
Confirm
</button>
<button
className="buddies--decline-button"
onClick={() => {
props.handleFriendrequest(item._links.decline.href);
}}
>
Decline
</button>
</div>
))}
</div>
</div>
</div>
);
}
Buddies.propTypes = {
activityBuddies: React.PropTypes.array,
endFriendship: React.PropTypes.func,
friendrequests: React.PropTypes.array,
handleFriendrequest: React.PropTypes.func,
};
The no-unused-prop-types-Rule shows an error for both the endFriendship and the handleFriendrequest props but both are used in my component.
I use eslint 3.4.0 and eslint-plugin-react 6.2.0.
I use the no-unused-prop-types-Rule as part of eslint-config-airbnb 11.0.0.
In the config it is set like this:
'react/no-unused-prop-types': ['error', {
customValidators: [
],
skipShapeProps: false,
}],
About this issue
- Original URL
- State: closed
- Created 8 years ago
- Comments: 39 (18 by maintainers)
Commits related to this issue
- fix lint errors We had to choose between disabling react/prop-types or react/no-unused-prop-types. Since react/no-unused-prop-types has a bug (see https://github.com/yannickcr/eslint-plugin-react/is... — committed to LearnersGuild/echo by deleted user 7 years ago
- fix lint errors We had to choose between disabling react/prop-types or react/no-unused-prop-types. Since react/no-unused-prop-types has a bug (see https://github.com/yannickcr/eslint-plugin-react/is... — committed to LearnersGuild/echo by deleted user 7 years ago
- fix lint errors We had to choose between disabling react/prop-types or react/no-unused-prop-types. Since react/no-unused-prop-types has a bug (see https://github.com/yannickcr/eslint-plugin-react/is... — committed to LearnersGuild/echo by deleted user 7 years ago
- adding test cases from #811 — committed to DianaSuvorova/eslint-plugin-react by DianaSuvorova 7 years ago
- adding test cases from #811 — committed to DianaSuvorova/eslint-plugin-react by DianaSuvorova 7 years ago
Counting used
nextPropsincomponentWillReceivePropsis a clear win for this rule, certainly.One more example of false positive:
Here
nameis marked as unused. In fact, all properties accessed via temporary local variable will be flagged as unused.Its a grand ambition to have a rule like this. JavaScript is a highly dynamic language and there is no way a static checker can detect unused props reliably. Turning it off may be the only sane and time-practical recourse. My 2 cents of course.
Similar to the componentWillReceiveProps example,
ownPropsused inmapStateToProps(while connecting with the redux store) are also not counted as used. E.g.@ljharb - do you think counting this can be considered?
It is a pity that is the unique working way to fix that 😦 .
mapStateToPropsis a lot harder because it’s redux-specific, and not tied to the component.However, wouldn’t a prop only used in
mapStateToPropsbe a prop you want to not pass to the component?Didn’t mean you specifically. We’re all replying to a closed thread (including myself).
Yes and as @ljharb pointed it out, its not a legit case. What I am saying is the maintainers will be more inclined to take up something that is not being debated in a closed thread with a use case that can be argued as not the most compelling example of a valid use case. Didn’t mean anything personally.
That sounds familiar. Did someone say so earlier? 😛
As much as I hate getting slapped around by a linter, I agree with @ljharb here.
getLocationsis poorly designed in this case. You can easily change the call in constructor tothis.getLocations(props)and avoid this whole issue in the first place.I like linting as much as the next person but in this case, the use case itself is not compelling. The authors do listen if there is a good use case. And linting is purely an opt-in thingy. You lint because you want your code to really look good, not because you want some figure head to give a seal of OK.
That said, there is no point in spamming a closed thread. If there are valid concerns, then a new issue should be opened.
I’m telling you that as a maintainer of this plugin, it’s not possible to do it reliably, because it’s not always pulling off of
this.props. Meaning, if there’s any chance whatsoever that the destructuring is not off of a props object, then we can’t pay attention to it. I’m sure we could cover your specific case, but doing so would risk doing the wrong thing for other cases, so we will not be covering your particular case. The fact that it’s an antipattern means that you have a better way to write your code anyways that remove the need for extra changes in this plugin.@ljharb, @ivarni - I agree with your point. What I was trying to achieve by keeping the “only being used in mapStateToProps” prop in
propTypeswas to ensure that I can use ReactPropTypesvalidations to enforce the requirement and the data type of that prop along with a default value if needed. Since this prop is not a part of the props finally being used, one can better remove it from thepropTypesdefinition, at the cost of missing the validation and default value.Having said that, the comments above are missing a fine detail here, the object returned by
mapStateToPropsis not really a “replacement” props object, since it is “merged” to the originalpropsobject. While I don’t agree that a prop being used only inmapStateToPropsneed not be passed to the component(given the example above), it’s perfectly valid to say thatmapStateToPropsis not a part of the actual React component class and thus trying to validate inputs tomapStateToPropsusing the React componentPropTypevalidations is not usual.Thank you for the fruitful discussion. I’ll just disable the rule with inline comments.
The
propTypesdescribe what props the component needs in order to function andmapStateToPropsis not really part of the component’s class so you’d need some different mechanism for ensuring that the redux store actually contains the properties you need in order to transform them to component props.React will also only check props that are actually passed on to the component itself and not those passed to
mapStateToProps.