Skip to content

Commit

Permalink
Fix false positives inside lifecycle methods
Browse files Browse the repository at this point in the history
This will prevent triggering on any member expression inside a lifecycle
method. Instead, it will do the naive checking of the node names for
`props`, `nextProps`, and `prevProps` which is already done here.
  • Loading branch information
jomasti committed Dec 28, 2018
1 parent a83d65c commit 55e5fc1
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 3 deletions.
7 changes: 4 additions & 3 deletions lib/util/usedPropTypes.js
Original file line number Diff line number Diff line change
Expand Up @@ -285,13 +285,14 @@ module.exports = function usedPropTypesInstructions(context, components, utils)
* @returns {Boolean} True if we are using a prop, false if not.
*/
function isPropTypesUsage(node) {
const isThisPropsUsage = node.object.type === 'ThisExpression' && node.property.name === 'props';
const isPropsUsage = isThisPropsUsage || node.object.name === 'nextProps' || node.object.name === 'prevProps';
const isClassUsage = (
(utils.getParentES6Component() || utils.getParentES5Component()) &&
((node.object.type === 'ThisExpression' && node.property.name === 'props')
|| isPropArgumentInSetStateUpdater(node))
(isThisPropsUsage || isPropArgumentInSetStateUpdater(node))
);
const isStatelessFunctionUsage = node.object.name === 'props' && !isAssignmentToProp(node);
return isClassUsage || isStatelessFunctionUsage || inLifeCycleMethod();
return isClassUsage || isStatelessFunctionUsage || (isPropsUsage && inLifeCycleMethod());
}

/**
Expand Down
77 changes: 77 additions & 0 deletions tests/lib/rules/prop-types.js
Original file line number Diff line number Diff line change
Expand Up @@ -2170,6 +2170,83 @@ ruleTester.run('prop-types', rule, {
pragma: 'Foo'
}
}
},
{
code: `
class Foo extends React.Component {
propTypes = {
actions: PropTypes.object.isRequired,
};
componentWillReceiveProps (nextProps) {
this.props.actions.doSomething();
}
componentWillUnmount () {
this.props.actions.doSomething();
}
render() {
return <div>foo</div>;
}
}
`,
parser: 'babel-eslint'
},
{
code: `
class Foo extends React.Component {
componentDidUpdate() { this.inputRef.focus(); }
render() {
return (
<div>
<input ref={(node) => { this.inputRef = node; }} />
</div>
)
}
}
`
},
{
code: `
class Foo extends React.Component {
componentDidUpdate(nextProps, nextState) {
const {
first_organization,
second_organization,
} = this.state;
return true;
}
render() {
return <div>hi</div>;
}
}
`
},
{
code: `
class Foo extends React.Component {
shouldComponentUpdate(nextProps) {
if (this.props.search !== nextProps.search) {
let query = nextProps.query;
let result = nextProps.list.filter(item => {
return (item.name.toLowerCase().includes(query.trim().toLowerCase()));
});
this.setState({ result });
return true;
}
}
render() {
return <div>foo</div>;
}
}
Foo.propTypes = {
search: PropTypes.object,
list: PropTypes.array,
query: PropTypes.string,
};
`
}
],

Expand Down

0 comments on commit 55e5fc1

Please sign in to comment.