diff --git a/lib/util/usedPropTypes.js b/lib/util/usedPropTypes.js index 9e19fe8b14..9270d8bcf0 100755 --- a/lib/util/usedPropTypes.js +++ b/lib/util/usedPropTypes.js @@ -135,25 +135,16 @@ function isInLifeCycleMethod(node, checkAsyncSafeLifeCycles) { } /** - * Check if the current node is in a setState updater method - * @return {boolean} true if we are in a setState updater, false if not + * Check if a function node is a setState updater + * @param {ASTNode} node a function node + * @return {boolean} */ -function inSetStateUpdater(context) { - let scope = context.getScope(); - while (scope) { - if ( - scope.block && scope.block.parent && - scope.block.parent.type === 'CallExpression' && - scope.block.parent.callee.property && - scope.block.parent.callee.property.name === 'setState' && - // Make sure we are in the updater not the callback - scope.block.parent.arguments[0].start === scope.block.start - ) { - return true; - } - scope = scope.upper; - } - return false; +function isSetStateUpdater(node) { + return node.parent.type === 'CallExpression' && + node.parent.callee.property && + node.parent.callee.property.name === 'setState' && + // Make sure we are in the updater not the callback + node.parent.arguments[0] === node; } function isPropArgumentInSetStateUpdater(context, name) { @@ -324,7 +315,7 @@ module.exports = function usedPropTypesInstructions(context, components, utils) break; } type = 'destructuring'; - const propParam = inSetStateUpdater(context) ? node.params[1] : node.params[0]; + const propParam = isSetStateUpdater(node) ? node.params[1] : node.params[0]; properties = propParam.type === 'AssignmentPattern' ? propParam.left.properties : propParam.properties; @@ -399,7 +390,7 @@ module.exports = function usedPropTypesInstructions(context, components, utils) * FunctionDeclaration, or FunctionExpression */ function markDestructuredFunctionArgumentsAsUsed(node) { - const param = node.params && inSetStateUpdater(context) ? node.params[1] : node.params[0]; + const param = node.params && isSetStateUpdater(node) ? node.params[1] : node.params[0]; const destructuring = param && ( param.type === 'ObjectPattern' || @@ -412,7 +403,7 @@ module.exports = function usedPropTypesInstructions(context, components, utils) } function handleSetStateUpdater(node) { - if (!node.params || node.params.length < 2 || !inSetStateUpdater(context)) { + if (!node.params || node.params.length < 2 || !isSetStateUpdater(node)) { return; } markPropTypesAsUsed(node); diff --git a/tests/lib/rules/prop-types.js b/tests/lib/rules/prop-types.js index 71714be846..abba1caf2a 100755 --- a/tests/lib/rules/prop-types.js +++ b/tests/lib/rules/prop-types.js @@ -2065,6 +2065,17 @@ ruleTester.run('prop-types', rule, { }; ` }, + { + code: ` + class Foo extends React.Component { + bar() { + this.setState((state, props) => { + function f(_, {aaaaaaa}) {} + }); + } + } + ` + }, { code: ` class Foo extends React.Component {