Skip to content

Commit dfeeb81

Browse files
authored
Merge pull request #2099 from jomasti/issue-2094
Fix false positives inside lifecycle methods
2 parents 254a84a + 55e5fc1 commit dfeeb81

File tree

2 files changed

+81
-3
lines changed

2 files changed

+81
-3
lines changed

lib/util/usedPropTypes.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -285,13 +285,14 @@ module.exports = function usedPropTypesInstructions(context, components, utils)
285285
* @returns {Boolean} True if we are using a prop, false if not.
286286
*/
287287
function isPropTypesUsage(node) {
288+
const isThisPropsUsage = node.object.type === 'ThisExpression' && node.property.name === 'props';
289+
const isPropsUsage = isThisPropsUsage || node.object.name === 'nextProps' || node.object.name === 'prevProps';
288290
const isClassUsage = (
289291
(utils.getParentES6Component() || utils.getParentES5Component()) &&
290-
((node.object.type === 'ThisExpression' && node.property.name === 'props')
291-
|| isPropArgumentInSetStateUpdater(node))
292+
(isThisPropsUsage || isPropArgumentInSetStateUpdater(node))
292293
);
293294
const isStatelessFunctionUsage = node.object.name === 'props' && !isAssignmentToProp(node);
294-
return isClassUsage || isStatelessFunctionUsage || inLifeCycleMethod();
295+
return isClassUsage || isStatelessFunctionUsage || (isPropsUsage && inLifeCycleMethod());
295296
}
296297

297298
/**

tests/lib/rules/prop-types.js

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2170,6 +2170,83 @@ ruleTester.run('prop-types', rule, {
21702170
pragma: 'Foo'
21712171
}
21722172
}
2173+
},
2174+
{
2175+
code: `
2176+
class Foo extends React.Component {
2177+
propTypes = {
2178+
actions: PropTypes.object.isRequired,
2179+
};
2180+
componentWillReceiveProps (nextProps) {
2181+
this.props.actions.doSomething();
2182+
}
2183+
2184+
componentWillUnmount () {
2185+
this.props.actions.doSomething();
2186+
}
2187+
2188+
render() {
2189+
return <div>foo</div>;
2190+
}
2191+
}
2192+
`,
2193+
parser: 'babel-eslint'
2194+
},
2195+
{
2196+
code: `
2197+
class Foo extends React.Component {
2198+
componentDidUpdate() { this.inputRef.focus(); }
2199+
render() {
2200+
return (
2201+
<div>
2202+
<input ref={(node) => { this.inputRef = node; }} />
2203+
</div>
2204+
)
2205+
}
2206+
}
2207+
`
2208+
},
2209+
{
2210+
code: `
2211+
class Foo extends React.Component {
2212+
componentDidUpdate(nextProps, nextState) {
2213+
const {
2214+
first_organization,
2215+
second_organization,
2216+
} = this.state;
2217+
return true;
2218+
}
2219+
render() {
2220+
return <div>hi</div>;
2221+
}
2222+
}
2223+
`
2224+
},
2225+
{
2226+
code: `
2227+
class Foo extends React.Component {
2228+
shouldComponentUpdate(nextProps) {
2229+
if (this.props.search !== nextProps.search) {
2230+
let query = nextProps.query;
2231+
let result = nextProps.list.filter(item => {
2232+
return (item.name.toLowerCase().includes(query.trim().toLowerCase()));
2233+
});
2234+
2235+
this.setState({ result });
2236+
2237+
return true;
2238+
}
2239+
}
2240+
render() {
2241+
return <div>foo</div>;
2242+
}
2243+
}
2244+
Foo.propTypes = {
2245+
search: PropTypes.object,
2246+
list: PropTypes.array,
2247+
query: PropTypes.string,
2248+
};
2249+
`
21732250
}
21742251
],
21752252

0 commit comments

Comments
 (0)