react-hooks/rules-of-hooks: detect issues in class properties (#31823)
Co-authored-by: Elizabeth Craig <elcraig@microsoft.com>
Miguel Jiménez Esún committed
Jan 6, 2025 at 12:12 UTC
301a18a6afeaea9c6113d7e459025ba69f436b24
5 files changed
+148
-54
packages/eslint-plugin-react-hooks/__tests__/ESLintRuleExhaustiveDeps-test.js
+2
-1
@@ -8300,6 +8300,7 @@ describe('rules-of-hooks/exhaustive-deps', () => {
8300
ecmaVersion: 6,
8301
sourceType: 'module',
8302
};
8303
+
8304
const languageOptionsV9 = {
8305
ecmaVersion: 6,
8306
sourceType: 'module',
@@ -8442,7 +8443,7 @@ describe('rules-of-hooks/exhaustive-deps', () => {
8443
parser: require('@typescript-eslint/parser-v5'),
8444
},
8445
}).run(
8445
- 'eslint: v9, parser: @typescript-eslint/parser@^5.0.0-0',
8446
+ 'eslint: v9, parser: @typescript-eslint/parser@^5.0.0',
8447
ReactHooksESLintRule,
8448
{
8449
valid: [
packages/eslint-plugin-react-hooks/__tests__/ESLintRulesOfHooks-test.js
+108
-11
@@ -12,7 +12,6 @@
12
const ESLintTesterV7 = require('eslint-v7').RuleTester;
13
const ESLintTesterV9 = require('eslint-v9').RuleTester;
14
const ReactHooksESLintPlugin = require('eslint-plugin-react-hooks');
15
-const BabelEslintParser = require('@babel/eslint-parser');
15
const ReactHooksESLintRule = ReactHooksESLintPlugin.rules['rules-of-hooks'];
16
17
/**
@@ -1561,19 +1560,117 @@ if (!process.env.CI) {
1560
}
1561
1562
describe('rules-of-hooks/rules-of-hooks', () => {
1564
- new ESLintTesterV7({
1565
- parser: require.resolve('babel-eslint'),
1563
+ const parserOptionsV7 = {
1564
+ ecmaFeatures: {
1565
+ jsx: true,
1566
+ },
1567
+ ecmaVersion: 6,
1568
+ sourceType: 'module',
1569
+ };
1570
+
1571
+ const languageOptionsV9 = {
1572
+ ecmaVersion: 6,
1573
+ sourceType: 'module',
1574
parserOptions: {
1567
- ecmaVersion: 6,
1568
- sourceType: 'module',
1575
+ ecmaFeatures: {
1576
+ jsx: true,
1577
+ },
1578
},
1570
- }).run('eslint: v7', ReactHooksESLintRule, tests);
1579
+ };
1580
+
1581
+ new ESLintTesterV7({
1582
+ parser: require.resolve('babel-eslint'),
1583
+ parserOptions: parserOptionsV7,
1584
+ }).run('eslint: v7, parser: babel-eslint', ReactHooksESLintRule, tests);
1585
1586
new ESLintTesterV9({
1587
languageOptions: {
1574
- parser: BabelEslintParser,
1575
- ecmaVersion: 6,
1576
- sourceType: 'module',
1577
- },
1578
- }).run('eslint: v9', ReactHooksESLintRule, tests);
1588
+ ...languageOptionsV9,
1589
+ parser: require('@babel/eslint-parser'),
1590
+ },
1591
+ }).run(
1592
+ 'eslint: v9, parser: @babel/eslint-parser',
1593
+ ReactHooksESLintRule,
1594
+ tests
1595
+ );
1596
+
1597
+ new ESLintTesterV7({
1598
+ parser: require.resolve('@typescript-eslint/parser-v2'),
1599
+ parserOptions: parserOptionsV7,
1600
+ }).run(
1601
+ 'eslint: v7, parser: @typescript-eslint/parser@2.x',
1602
+ ReactHooksESLintRule,
1603
+ tests
1604
+ );
1605
+
1606
+ new ESLintTesterV9({
1607
+ languageOptions: {
1608
+ ...languageOptionsV9,
1609
+ parser: require('@typescript-eslint/parser-v2'),
1610
+ },
1611
+ }).run(
1612
+ 'eslint: v9, parser: @typescript-eslint/parser@2.x',
1613
+ ReactHooksESLintRule,
1614
+ tests
1615
+ );
1616
+
1617
+ new ESLintTesterV7({
1618
+ parser: require.resolve('@typescript-eslint/parser-v3'),
1619
+ parserOptions: parserOptionsV7,
1620
+ }).run(
1621
+ 'eslint: v7, parser: @typescript-eslint/parser@3.x',
1622
+ ReactHooksESLintRule,
1623
+ tests
1624
+ );
1625
+
1626
+ new ESLintTesterV9({
1627
+ languageOptions: {
1628
+ ...languageOptionsV9,
1629
+ parser: require('@typescript-eslint/parser-v3'),
1630
+ },
1631
+ }).run(
1632
+ 'eslint: v9, parser: @typescript-eslint/parser@3.x',
1633
+ ReactHooksESLintRule,
1634
+ tests
1635
+ );
1636
+
1637
+ new ESLintTesterV7({
1638
+ parser: require.resolve('@typescript-eslint/parser-v4'),
1639
+ parserOptions: parserOptionsV7,
1640
+ }).run(
1641
+ 'eslint: v7, parser: @typescript-eslint/parser@4.x',
1642
+ ReactHooksESLintRule,
1643
+ tests
1644
+ );
1645
+
1646
+ new ESLintTesterV9({
1647
+ languageOptions: {
1648
+ ...languageOptionsV9,
1649
+ parser: require('@typescript-eslint/parser-v4'),
1650
+ },
1651
+ }).run(
1652
+ 'eslint: v9, parser: @typescript-eslint/parser@4.x',
1653
+ ReactHooksESLintRule,
1654
+ tests
1655
+ );
1656
+
1657
+ new ESLintTesterV7({
1658
+ parser: require.resolve('@typescript-eslint/parser-v5'),
1659
+ parserOptions: parserOptionsV7,
1660
+ }).run(
1661
+ 'eslint: v7, parser: @typescript-eslint/parser@^5.0.0-0',
1662
+ ReactHooksESLintRule,
1663
+ tests
1664
+ );
1665
+
1666
+ new ESLintTesterV9({
1667
+ languageOptions: {
1668
+ ...languageOptionsV9,
1669
+ parser: require('@typescript-eslint/parser-v5'),
1670
+ },
1671
+ }).run(
1672
+ 'eslint: v9, parser: @typescript-eslint/parser@^5.0.0',
1673
+ ReactHooksESLintRule,
1674
+ tests
1675
+ );
1676
});
packages/eslint-plugin-react-hooks/package.json
+1
-1
@@ -35,7 +35,7 @@
35
"@typescript-eslint/parser-v2": "npm:@typescript-eslint/parser@^2.26.0",
36
"@typescript-eslint/parser-v3": "npm:@typescript-eslint/parser@^3.10.0",
37
"@typescript-eslint/parser-v4": "npm:@typescript-eslint/parser@^4.1.0",
38
- "@typescript-eslint/parser-v5": "npm:@typescript-eslint/parser@^5.0.0-0",
38
+ "@typescript-eslint/parser-v5": "npm:@typescript-eslint/parser@^5.62.0",
39
"babel-eslint": "^10.0.3",
40
"eslint-v7": "npm:eslint@^7.7.0",
41
"eslint-v9": "npm:eslint@^9.0.0"
packages/eslint-plugin-react-hooks/src/RulesOfHooks.js
+2
-1
@@ -549,7 +549,8 @@ export default {
549
} else if (
550
codePathNode.parent &&
551
(codePathNode.parent.type === 'MethodDefinition' ||
552
- codePathNode.parent.type === 'ClassProperty') &&
552
+ codePathNode.parent.type === 'ClassProperty' ||
553
+ codePathNode.parent.type === 'PropertyDefinition') &&
554
codePathNode.parent.value === codePathNode
555
) {
556
// Custom message for hooks inside a class
yarn.lock
+35
-40
@@ -3536,15 +3536,15 @@
3536
"@typescript-eslint/typescript-estree" "4.1.0"
3537
debug "^4.1.1"
3538
3539
-"@typescript-eslint/parser-v5@npm:@typescript-eslint/parser@^5.0.0-0":
3540
- version "5.0.0-alpha.25"
3541
- resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.0.0-alpha.25.tgz#d966eb8b2cf97f0134a5589791017e0a720bb995"
3542
- integrity sha512-e0Q2fWVXle8l9pCCV2K/pQrn0Wyp8nV/Gp8AbEUqP6xLfgrOxejzcERP9y5x1rnwrp7pPXZhticsNLjqljhh6w==
3543
- dependencies:
3544
- "@typescript-eslint/scope-manager" "5.0.0-alpha.25+faf2d1d2"
3545
- "@typescript-eslint/types" "5.0.0-alpha.25+faf2d1d2"
3546
- "@typescript-eslint/typescript-estree" "5.0.0-alpha.25+faf2d1d2"
3547
- debug "^4.3.1"
3539
+"@typescript-eslint/parser-v5@npm:@typescript-eslint/parser@^5.62.0":
3540
+ version "5.62.0"
3541
+ resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.62.0.tgz#1b63d082d849a2fcae8a569248fbe2ee1b8a56c7"
3542
+ integrity sha512-VlJEV0fOQ7BExOsHYAGrgbEiZoi8D+Bl2+f6V2RrXerRSylnp+ZBHmPvaIa8cz0Ajx7WO7Z5RqfgYg7ED1nRhA==
3543
+ dependencies:
3544
+ "@typescript-eslint/scope-manager" "5.62.0"
3545
+ "@typescript-eslint/types" "5.62.0"
3546
+ "@typescript-eslint/typescript-estree" "5.62.0"
3547
+ debug "^4.3.4"
3548
3549
"@typescript-eslint/scope-manager@4.1.0":
3550
version "4.1.0"
@@ -3554,13 +3554,13 @@
3554
"@typescript-eslint/types" "4.1.0"
3555
"@typescript-eslint/visitor-keys" "4.1.0"
3556
3557
-"@typescript-eslint/scope-manager@5.0.0-alpha.25+faf2d1d2":
3558
- version "5.0.0-alpha.25"
3559
- resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.0.0-alpha.25.tgz#eb90cb682f6a3a14ba9afc4bd7c1f66cf362e1b0"
3560
- integrity sha512-tZumo5HziFbOI+unwQ7Xgimn4FHltg20TCxVCU2tl7YyFhiQl1WxnmhU7/1MUNWXzK9RA88MRKvUON1lgK1FLw==
3557
+"@typescript-eslint/scope-manager@5.62.0":
3558
+ version "5.62.0"
3559
+ resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.62.0.tgz#d9457ccc6a0b8d6b37d0eb252a23022478c5460c"
3560
+ integrity sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w==
3561
dependencies:
3562
- "@typescript-eslint/types" "5.0.0-alpha.25+faf2d1d2"
3563
- "@typescript-eslint/visitor-keys" "5.0.0-alpha.25+faf2d1d2"
3562
+ "@typescript-eslint/types" "5.62.0"
3563
+ "@typescript-eslint/visitor-keys" "5.62.0"
3564
3565
"@typescript-eslint/scope-manager@6.21.0":
3566
version "6.21.0"
@@ -3580,10 +3580,10 @@
3580
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.1.0.tgz#edbd3fec346f34e13ce7aa176b03b497a32c496a"
3581
integrity sha512-rkBqWsO7m01XckP9R2YHVN8mySOKKY2cophGM8K5uDK89ArCgahItQYdbg/3n8xMxzu2elss+an1TphlUpDuJw==
3582
3583
-"@typescript-eslint/types@5.0.0-alpha.25+faf2d1d2":
3584
- version "5.0.0-alpha.25"
3585
- resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.0.0-alpha.25.tgz#2c5aaaee8d41d08fbb91193cc6df482374700b2e"
3586
- integrity sha512-M9PZ+m1vD+UaBt+9hJ1bXTA94s4fvY3fOQkwYxrtreqqdzaiNcW8F5GAO3dthzmS+6II+XAsWfCQzCoBvoiOrw==
3583
+"@typescript-eslint/types@5.62.0":
3584
+ version "5.62.0"
3585
+ resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.62.0.tgz#258607e60effa309f067608931c3df6fed41fd2f"
3586
+ integrity sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==
3587
3588
"@typescript-eslint/types@6.21.0":
3589
version "6.21.0"
@@ -3631,17 +3631,17 @@
3631
semver "^7.3.2"
3632
tsutils "^3.17.1"
3633
3634
-"@typescript-eslint/typescript-estree@5.0.0-alpha.25+faf2d1d2":
3635
- version "5.0.0-alpha.25"
3636
- resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.0.0-alpha.25.tgz#1e9ad3464c93fffb1b17d8cc3e2523ae6add930b"
3637
- integrity sha512-EIEX4TSWGIBBi9DMZd8FZoI52Ua6hkHj2T8ah83BEBVMS9wCJDZyryuw0PHTesA2ZB5yiQbtNQrrODLJxz1hAw==
3634
+"@typescript-eslint/typescript-estree@5.62.0":
3635
+ version "5.62.0"
3636
+ resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.62.0.tgz#7d17794b77fabcac615d6a48fb143330d962eb9b"
3637
+ integrity sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==
3638
dependencies:
3639
- "@typescript-eslint/types" "5.0.0-alpha.25+faf2d1d2"
3640
- "@typescript-eslint/visitor-keys" "5.0.0-alpha.25+faf2d1d2"
3641
- debug "^4.3.1"
3642
- globby "^11.0.3"
3643
- is-glob "^4.0.1"
3644
- semver "^7.3.5"
3639
+ "@typescript-eslint/types" "5.62.0"
3640
+ "@typescript-eslint/visitor-keys" "5.62.0"
3641
+ debug "^4.3.4"
3642
+ globby "^11.1.0"
3643
+ is-glob "^4.0.3"
3644
+ semver "^7.3.7"
3645
tsutils "^3.21.0"
3646
3647
"@typescript-eslint/typescript-estree@6.21.0":
@@ -3686,13 +3686,13 @@
3686
"@typescript-eslint/types" "4.1.0"
3687
eslint-visitor-keys "^2.0.0"
3688
3689
-"@typescript-eslint/visitor-keys@5.0.0-alpha.25+faf2d1d2":
3690
- version "5.0.0-alpha.25"
3691
- resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.0.0-alpha.25.tgz#0b4a909d4020094e638dee1ff72e12d24783c94b"
3692
- integrity sha512-vh5AIlr3wxkhFMreop5Y1Wi5Sc9oK03J8+SiyKMEEAqwWmk6e2ryHr1001oWRuK4e6d/CjVNa73omERCWcTXTg==
3689
+"@typescript-eslint/visitor-keys@5.62.0":
3690
+ version "5.62.0"
3691
+ resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.62.0.tgz#2174011917ce582875954ffe2f6912d5931e353e"
3692
+ integrity sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==
3693
dependencies:
3694
- "@typescript-eslint/types" "5.0.0-alpha.25+faf2d1d2"
3695
- eslint-visitor-keys "^3.0.0"
3694
+ "@typescript-eslint/types" "5.62.0"
3695
+ eslint-visitor-keys "^3.3.0"
3696
3697
"@typescript-eslint/visitor-keys@6.21.0":
3698
version "6.21.0"
@@ -7522,11 +7522,6 @@ eslint-visitor-keys@^2.0.0:
7522
resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-2.0.0.tgz#21fdc8fbcd9c795cc0321f0563702095751511a8"
7523
integrity sha512-QudtT6av5WXels9WjIM7qz1XD1cWGvX4gGXvp/zBn9nXG02D0utdU3Em2m/QjTnrsk6bBjmCygl3rmj118msQQ==
7524
7525
-eslint-visitor-keys@^3.0.0:
7526
- version "3.0.0"
7527
- resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.0.0.tgz#e32e99c6cdc2eb063f204eda5db67bfe58bb4186"
7528
- integrity sha512-mJOZa35trBTb3IyRmo8xmKBZlxf+N7OnUl4+ZhJHs/r+0770Wh/LEACE2pqMGMe27G/4y8P2bYGk4J70IC5k1Q==
7529
-
7525
eslint-visitor-keys@^3.3.0, eslint-visitor-keys@^3.4.1, eslint-visitor-keys@^3.4.3:
7526
version "3.4.3"
7527
resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz#0cd72fe8550e3c2eae156a96a4dddcd1c8ac5800"