diff --git a/lib/util/Components.js b/lib/util/Components.js index fec2d2e50e..6c4f18e074 100644 --- a/lib/util/Components.js +++ b/lib/util/Components.js @@ -362,12 +362,13 @@ function componentRule(rule, context) { var isFunction = /Function/.test(node.type); // Functions var isMethod = node.parent && node.parent.type === 'MethodDefinition'; // Classes methods var isArgument = node.parent && node.parent.type === 'CallExpression'; // Arguments (callback, etc.) + var isJSX = node.parent && node.parent.type === 'JSXExpressionContainer'; // Stop moving up if we reach a class or an argument (like a callback) if (isClass || isArgument) { return null; } // Return the node if it is a function that is not a class method - if (isFunction && !isMethod) { + if (isFunction && !isMethod && !isJSX) { return node; } scope = scope.upper; diff --git a/tests/lib/rules/no-unused-prop-types.js b/tests/lib/rules/no-unused-prop-types.js index 8d255add46..02a6032273 100644 --- a/tests/lib/rules/no-unused-prop-types.js +++ b/tests/lib/rules/no-unused-prop-types.js @@ -1428,6 +1428,39 @@ ruleTester.run('no-unused-prop-types', rule, { '};' ].join('\n'), parserOptions: parserOptions + }, { + // `no-unused-prop-types` in jsx expressions - [Issue #885] + code: [ + 'const PagingBlock = function(props) {', + ' return (', + ' ', + ' props.previousPage()}/>', + ' props.nextPage()}/>', + ' ', + ' );', + '};', + + 'PagingBlock.propTypes = {', + ' nextPage: React.PropTypes.func.isRequired,', + ' previousPage: React.PropTypes.func.isRequired,', + '};' + ].join('\n'), + parserOptions: parserOptions + }, { + // `no-unused-prop-types` rest param props in jsx expressions - [Issue #885] + code: [ + 'const PagingBlock = function(props) {', + ' return (', + ' ', + ' );', + '};', + + 'PagingBlock.propTypes = {', + ' nextPage: React.PropTypes.func.isRequired,', + ' previousPage: React.PropTypes.func.isRequired,', + '};' + ].join('\n'), + parserOptions: parserOptions } ],