Skip to content

Commit dcf9766

Browse files
committed
[fix] prop-types: false positive with setState updator
1 parent 47c4c8b commit dcf9766

File tree

2 files changed

+23
-21
lines changed

2 files changed

+23
-21
lines changed

lib/util/usedPropTypes.js

Lines changed: 12 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -135,25 +135,16 @@ function isInLifeCycleMethod(node, checkAsyncSafeLifeCycles) {
135135
}
136136

137137
/**
138-
* Check if the current node is in a setState updater method
139-
* @return {boolean} true if we are in a setState updater, false if not
138+
* Check if a function node is a setState updater
139+
* @param {ASTNode} node a function node
140+
* @return {boolean}
140141
*/
141-
function inSetStateUpdater(context) {
142-
let scope = context.getScope();
143-
while (scope) {
144-
if (
145-
scope.block && scope.block.parent &&
146-
scope.block.parent.type === 'CallExpression' &&
147-
scope.block.parent.callee.property &&
148-
scope.block.parent.callee.property.name === 'setState' &&
149-
// Make sure we are in the updater not the callback
150-
scope.block.parent.arguments[0].start === scope.block.start
151-
) {
152-
return true;
153-
}
154-
scope = scope.upper;
155-
}
156-
return false;
142+
function isSetStateUpdater(node) {
143+
return node.parent.type === 'CallExpression' &&
144+
node.parent.callee.property &&
145+
node.parent.callee.property.name === 'setState' &&
146+
// Make sure we are in the updater not the callback
147+
node.parent.arguments[0] === node;
157148
}
158149

159150
function isPropArgumentInSetStateUpdater(context, name) {
@@ -324,7 +315,7 @@ module.exports = function usedPropTypesInstructions(context, components, utils)
324315
break;
325316
}
326317
type = 'destructuring';
327-
const propParam = inSetStateUpdater(context) ? node.params[1] : node.params[0];
318+
const propParam = isSetStateUpdater(node) ? node.params[1] : node.params[0];
328319
properties = propParam.type === 'AssignmentPattern' ?
329320
propParam.left.properties :
330321
propParam.properties;
@@ -399,7 +390,7 @@ module.exports = function usedPropTypesInstructions(context, components, utils)
399390
* FunctionDeclaration, or FunctionExpression
400391
*/
401392
function markDestructuredFunctionArgumentsAsUsed(node) {
402-
const param = node.params && inSetStateUpdater(context) ? node.params[1] : node.params[0];
393+
const param = node.params && isSetStateUpdater(node) ? node.params[1] : node.params[0];
403394

404395
const destructuring = param && (
405396
param.type === 'ObjectPattern' ||
@@ -412,7 +403,7 @@ module.exports = function usedPropTypesInstructions(context, components, utils)
412403
}
413404

414405
function handleSetStateUpdater(node) {
415-
if (!node.params || node.params.length < 2 || !inSetStateUpdater(context)) {
406+
if (!node.params || node.params.length < 2 || !isSetStateUpdater(node)) {
416407
return;
417408
}
418409
markPropTypesAsUsed(node);

tests/lib/rules/prop-types.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2065,6 +2065,17 @@ ruleTester.run('prop-types', rule, {
20652065
};
20662066
`
20672067
},
2068+
{
2069+
code: `
2070+
class Foo extends React.Component {
2071+
bar() {
2072+
this.setState((state, props) => {
2073+
function f(_, {aaaaaaa}) {}
2074+
});
2075+
}
2076+
}
2077+
`
2078+
},
20682079
{
20692080
code: `
20702081
class Foo extends React.Component {

0 commit comments

Comments
 (0)