react-hooks/exhaustive-deps: Handle optional chained methods as dependency (#20204) (#20247)
Ari Perkkiö committed
Mar 24, 2021 at 18:45 UTC
eb58c3909aa19fb6ffbed27b9c9dba4aada3cb8e
2 files changed
+35
packages/eslint-plugin-react-hooks/__tests__/ESLintRuleExhaustiveDeps-test.js
+30
@@ -3629,6 +3629,36 @@ const tests = {
3629
},
3630
],
3631
},
3632
+ {
3633
+ code: normalizeIndent`
3634
+ function MyComponent(props) {
3635
+ useEffect(() => {}, [props?.attribute.method()]);
3636
+ }
3637
+ `,
3638
+ errors: [
3639
+ {
3640
+ message:
3641
+ 'React Hook useEffect has a complex expression in the dependency array. ' +
3642
+ 'Extract it to a separate variable so it can be statically checked.',
3643
+ suggestions: undefined,
3644
+ },
3645
+ ],
3646
+ },
3647
+ {
3648
+ code: normalizeIndent`
3649
+ function MyComponent(props) {
3650
+ useEffect(() => {}, [props.method()]);
3651
+ }
3652
+ `,
3653
+ errors: [
3654
+ {
3655
+ message:
3656
+ 'React Hook useEffect has a complex expression in the dependency array. ' +
3657
+ 'Extract it to a separate variable so it can be statically checked.',
3658
+ suggestions: undefined,
3659
+ },
3660
+ ],
3661
+ },
3662
{
3663
code: normalizeIndent`
3664
function MyComponent() {
packages/eslint-plugin-react-hooks/src/ExhaustiveDeps.js
+5
@@ -1656,6 +1656,11 @@ function analyzePropertyChain(node, optionalChains) {
1656
return result;
1657
} else if (node.type === 'ChainExpression' && !node.computed) {
1658
const expression = node.expression;
1659
+
1660
+ if (expression.type === 'CallExpression') {
1661
+ throw new Error(`Unsupported node type: ${expression.type}`);
1662
+ }
1663
+
1664
const object = analyzePropertyChain(expression.object, optionalChains);
1665
const property = analyzePropertyChain(expression.property, null);
1666
const result = `${object}.${property}`;