From 860ebead6d9d910e329840aeac5cc58fd3fee6df Mon Sep 17 00:00:00 2001 From: Veda Date: Sun, 6 Jun 2021 02:01:42 +0530 Subject: [PATCH] [Fix] `destructuring-assignment`, `no-multi-comp`, `no-unstable-nested-components`, component detection: improve component detection --- CHANGELOG.md | 4 +- lib/util/Components.js | 18 ++++++ tests/lib/rules/destructuring-assignment.js | 59 +++++++++++++++++++ tests/lib/rules/no-multi-comp.js | 4 +- .../rules/no-unstable-nested-components.js | 29 +++++---- 5 files changed, 96 insertions(+), 18 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6c2fc9b793..9e2ebbd74c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,11 +6,13 @@ This change log adheres to standards from [Keep a CHANGELOG](http://keepachangel ## Unreleased ### Fixed -* component detection: use `estraverse` to improve component detection ([#2992][] @Wesitos) +* component detection: use `estraverse` to improve component detection ([#2992][] @Wesitos) +* [`destructuring-assignment`], [`no-multi-comp`], [`no-unstable-nested-components`], component detection: improve component detection ([#3001][] @vedadeepta) ### Changed * [Docs] [`jsx-no-bind`]: updates discussion of refs ([#2998][] @dimitropoulos) +[#3001]: https://github.com/yannickcr/eslint-plugin-react/pull/3001 [#2998]: https://github.com/yannickcr/eslint-plugin-react/pull/2998 [#2992]: https://github.com/yannickcr/eslint-plugin-react/pull/2992 diff --git a/lib/util/Components.js b/lib/util/Components.js index 37761cc556..0ba329dae5 100644 --- a/lib/util/Components.js +++ b/lib/util/Components.js @@ -651,6 +651,8 @@ function componentRule(rule, context) { return undefined; } if (utils.isInAllowedPositionForComponent(node) && utils.isReturningJSXOrNull(node)) { + if (utils.isParentComponentNotStatelessComponent(node)) return undefined; + const isMethod = node.parent.type === 'Property' && node.parent.method; if (isMethod && !isFirstLetterCapitalized(node.parent.key.name)) { @@ -798,6 +800,18 @@ function componentRule(rule, context) { // Return the component return components.add(componentNode, 1); + }, + + isParentComponentNotStatelessComponent(node) { + return ( + node.parent + && node.parent.key + && node.parent.key.type === 'Identifier' + // custom component functions must start with a capital letter (returns false otherwise) + && node.parent.key.name.charAt(0) === node.parent.key.name.charAt(0).toLowerCase() + // react render function cannot have params + && !!(node.params || []).length + ); } }; @@ -846,6 +860,7 @@ function componentRule(rule, context) { components.add(node, 0); return; } + const component = utils.getParentComponent(); if ( !component @@ -863,6 +878,7 @@ function componentRule(rule, context) { components.add(node, 0); return; } + node = utils.getParentComponent(); if (!node) { return; @@ -875,7 +891,9 @@ function componentRule(rule, context) { components.add(node, 0); return; } + const component = utils.getParentComponent(); + if ( !component || (component.parent && component.parent.type === 'JSXExpressionContainer') diff --git a/tests/lib/rules/destructuring-assignment.js b/tests/lib/rules/destructuring-assignment.js index b1b5a333a1..bf6eb46fa9 100644 --- a/tests/lib/rules/destructuring-assignment.js +++ b/tests/lib/rules/destructuring-assignment.js @@ -196,6 +196,43 @@ ruleTester.run('destructuring-assignment', rule, { }, }; ` + }, { + code: ` + const columns = [ + { + render: (val) => { + if (val.url) { + return ( + + {val.test} + + ); + } + return null; + }, + }, + ]; + ` + }, { + code: ` + const columns = [ + { + render: val => {val}, + }, + { + someRenderFunc: function(val) { + if (val.url) { + return ( + + {val.test} + + ); + } + return null; + }, + }, + ]; + ` }], invalid: [{ @@ -353,5 +390,27 @@ ruleTester.run('destructuring-assignment', rule, { messageId: 'noDestructAssignment', data: {type: 'state'} }] + }, { + code: ` + const columns = [ + { + CustomComponentName: function(props) { + if (props.url) { + return ( + + {props.test} + + ); + } + return null; + }, + }, + ]; + `, + parser: parsers.BABEL_ESLINT, + errors: [{ + messageId: 'useDestructAssignment', + data: {type: 'props'} + }] }] }); diff --git a/tests/lib/rules/no-multi-comp.js b/tests/lib/rules/no-multi-comp.js index e2cbdc18a8..8c9bd824b4 100644 --- a/tests/lib/rules/no-multi-comp.js +++ b/tests/lib/rules/no-multi-comp.js @@ -316,11 +316,11 @@ ruleTester.run('no-multi-comp', rule, { }, { code: [ 'export default {', - ' renderHello(props) {', + ' RenderHello(props) {', ' let {name} = props;', ' return
{name}
;', ' },', - ' renderHello2(props) {', + ' RenderHello2(props) {', ' let {name} = props;', ' return
{name}
;', ' }', diff --git a/tests/lib/rules/no-unstable-nested-components.js b/tests/lib/rules/no-unstable-nested-components.js index d6df486d86..159816af8b 100644 --- a/tests/lib/rules/no-unstable-nested-components.js +++ b/tests/lib/rules/no-unstable-nested-components.js @@ -490,6 +490,20 @@ ruleTester.run('no-unstable-nested-components', rule, { }, }); ` + }, + { + code: ` + function ParentComponent() { + const rows = [ + { + name: 'A', + notPrefixedWithRender: (props) => + }, + ]; + + return ; + } + ` } /* TODO These minor cases are currently falsely marked due to component detection { @@ -1010,21 +1024,6 @@ ruleTester.run('no-unstable-nested-components', rule, { `, errors: [{message: ERROR_MESSAGE_COMPONENT_AS_PROPS}] }, - { - code: ` - function ParentComponent() { - const rows = [ - { - name: 'A', - notPrefixedWithRender: (props) => - }, - ]; - - return
; - } - `, - errors: [{message: ERROR_MESSAGE}] - }, { code: ` class ParentComponent extends React.Component {