Skip to content

Commit c8159fc

Browse files
golopotljharb
authored andcommitted
[Perf] component detection: improve performance by avoiding traversing parents unnecessarily (jsx-eslint#3459)
1 parent 4360fa3 commit c8159fc

File tree

3 files changed

+24
-22
lines changed

3 files changed

+24
-22
lines changed

CHANGELOG.md

+5
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,11 @@ This change log adheres to standards from [Keep a CHANGELOG](https://keepachange
55

66
## Unreleased
77

8+
### Changed
9+
* [Perf] component detection: improve performance by avoiding traversing parents unnecessarily ([#3459][] @golopot)
10+
11+
[#3459]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3459
12+
813
## [7.31.10] - 2022.10.10
914

1015
### Fixed

lib/util/Components.js

+18-21
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ class Components {
109109
set(node, props) {
110110
const list = Lists.get(this);
111111
let component = list[getId(node)];
112-
while (!component) {
112+
while (!component || component.confidence < 1) {
113113
node = node.parent;
114114
if (!node) {
115115
return;
@@ -477,7 +477,6 @@ function componentRule(rule, context) {
477477
}
478478

479479
if (node.type === 'FunctionExpression' || node.type === 'ArrowFunctionExpression') {
480-
const isMethod = parent.type === 'Property' && parent.method;
481480
const isPropertyAssignment = parent.type === 'AssignmentExpression'
482481
&& parent.left.type === 'MemberExpression';
483482
const isModuleExportsAssignment = isPropertyAssignment
@@ -562,6 +561,18 @@ function componentRule(rule, context) {
562561
return undefined;
563562
}
564563

564+
if (
565+
node.parent.type === 'Property' && (
566+
(node.parent.method && !node.parent.computed) // case: { f() { return ... } }
567+
|| (!node.id && !node.parent.computed) // case: { f: () => ... }
568+
)
569+
) {
570+
if (isFirstLetterCapitalized(node.parent.key.name) && utils.isReturningJSX(node)) {
571+
return node;
572+
}
573+
return undefined;
574+
}
575+
565576
// Case like `React.memo(() => <></>)` or `React.forwardRef(...)`
566577
const pragmaComponentWrapper = utils.getPragmaComponentWrapper(node);
567578
if (pragmaComponentWrapper && utils.isReturningJSXOrNull(node)) {
@@ -576,10 +587,6 @@ function componentRule(rule, context) {
576587
return undefined;
577588
}
578589

579-
if (isMethod && !isFirstLetterCapitalized(node.parent.key.name)) {
580-
return utils.isReturningJSX(node) ? node : undefined;
581-
}
582-
583590
if (node.id) {
584591
return isFirstLetterCapitalized(node.id.name) ? node : undefined;
585592
}
@@ -853,13 +860,8 @@ function componentRule(rule, context) {
853860
return;
854861
}
855862

856-
const component = utils.getParentComponent();
857-
if (
858-
!component
859-
|| (component.parent && component.parent.type === 'JSXExpressionContainer')
860-
) {
861-
// Ban the node if we cannot find a parent component
862-
components.add(node, 0);
863+
const component = utils.getStatelessComponent(node);
864+
if (!component) {
863865
return;
864866
}
865867
components.add(component, 2);
@@ -871,7 +873,7 @@ function componentRule(rule, context) {
871873
return;
872874
}
873875

874-
node = utils.getParentComponent();
876+
node = utils.getStatelessComponent(node);
875877
if (!node) {
876878
return;
877879
}
@@ -884,13 +886,8 @@ function componentRule(rule, context) {
884886
return;
885887
}
886888

887-
const component = utils.getParentComponent();
888-
if (
889-
!component
890-
|| (component.parent && component.parent.type === 'JSXExpressionContainer')
891-
) {
892-
// Ban the node if we cannot find a parent component
893-
components.add(node, 0);
889+
const component = utils.getStatelessComponent(node);
890+
if (!component) {
894891
return;
895892
}
896893
components.add(component, 2);

tests/lib/rules/destructuring-assignment.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -459,7 +459,7 @@ ruleTester.run('destructuring-assignment', rule, {
459459
},
460460
{
461461
code: `
462-
var Hello = React.createClass({
462+
var Hello = createReactClass({
463463
render: function() {
464464
return <Text>{this.props.foo}</Text>;
465465
}

0 commit comments

Comments
 (0)