Skip to content

Commit

Permalink
Handle the long tail of nodes that will be referentially unique
Browse files Browse the repository at this point in the history
  • Loading branch information
captbaritone committed Aug 12, 2020
1 parent 75fcb35 commit 4b6e20e
Show file tree
Hide file tree
Showing 2 changed files with 187 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1391,14 +1391,6 @@ const tests = {
}
`,
},
{
code: normalizeIndent`
function useFoo(){
const foo = new MyObj();
return useMemo(() => foo, [foo]);
}
`,
},
{
code: normalizeIndent`
function useFoo(){
Expand Down Expand Up @@ -7305,6 +7297,150 @@ const tests = {
},
],
},
{
code: normalizeIndent`
function Foo() {
const foo = <>Hi!</>;
useMemo(() => {
console.log(foo);
}, [foo]);
}
`,
errors: [
{
message:
"The 'foo' JSX fragment makes the dependencies of useMemo Hook (at line 6) change on every render. " +
"Move it inside the useMemo callback. Alternatively, wrap the construction of 'foo' in its own useMemo() Hook.",
suggestions: undefined,
},
],
},
{
code: normalizeIndent`
function Foo() {
const foo = <div>Hi!</div>;
useMemo(() => {
console.log(foo);
}, [foo]);
}
`,
errors: [
{
message:
"The 'foo' JSX element makes the dependencies of useMemo Hook (at line 6) change on every render. " +
"Move it inside the useMemo callback. Alternatively, wrap the construction of 'foo' in its own useMemo() Hook.",
suggestions: undefined,
},
],
},
{
code: normalizeIndent`
function Foo() {
const foo = bar = {};
useMemo(() => {
console.log(foo);
}, [foo]);
}
`,
errors: [
{
message:
"The 'foo' assignment expression makes the dependencies of useMemo Hook (at line 6) change on every render. " +
"Move it inside the useMemo callback. Alternatively, wrap the construction of 'foo' in its own useMemo() Hook.",
suggestions: undefined,
},
],
},
{
code: normalizeIndent`
function Foo() {
const foo = new String('foo'); // Note 'foo' will be boxed, and thus an object and thus compared by reference.
useMemo(() => {
console.log(foo);
}, [foo]);
}
`,
errors: [
{
message:
"The 'foo' object construction makes the dependencies of useMemo Hook (at line 6) change on every render. " +
"Move it inside the useMemo callback. Alternatively, wrap the construction of 'foo' in its own useMemo() Hook.",
suggestions: undefined,
},
],
},
{
code: normalizeIndent`
function Foo() {
const foo = new Map([]);
useMemo(() => {
console.log(foo);
}, [foo]);
}
`,
errors: [
{
message:
"The 'foo' object construction makes the dependencies of useMemo Hook (at line 6) change on every render. " +
"Move it inside the useMemo callback. Alternatively, wrap the construction of 'foo' in its own useMemo() Hook.",
suggestions: undefined,
},
],
},
{
code: normalizeIndent`
function Foo() {
const foo = /reg/;
useMemo(() => {
console.log(foo);
}, [foo]);
}
`,
errors: [
{
message:
"The 'foo' regular expression makes the dependencies of useMemo Hook (at line 6) change on every render. " +
"Move it inside the useMemo callback. Alternatively, wrap the construction of 'foo' in its own useMemo() Hook.",
suggestions: undefined,
},
],
},
{
code: normalizeIndent`
function Foo() {
const foo = ({}: any);
useMemo(() => {
console.log(foo);
}, [foo]);
}
`,
errors: [
{
message:
"The 'foo' object makes the dependencies of useMemo Hook (at line 6) change on every render. " +
"Move it inside the useMemo callback. Alternatively, wrap the construction of 'foo' in its own useMemo() Hook.",
suggestions: undefined,
},
],
},
{
code: normalizeIndent`
function Foo() {
class Bar {};
useMemo(() => {
console.log(new Bar());
}, [Bar]);
}
`,
errors: [
{
message:
"The 'Bar' class makes the dependencies of useMemo Hook (at line 6) change on every render. " +
"Move it inside the useMemo callback. Alternatively, wrap the construction of 'Bar' in its own useMemo() Hook.",
suggestions: undefined,
},
],
},
],
};

Expand Down Expand Up @@ -7683,6 +7819,24 @@ const testsTypescript = {
},
],
},
{
code: normalizeIndent`
function Foo() {
const foo = {} as any;;
useMemo(() => {
console.log(foo);
}, [foo]);
}
`,
errors: [
{
message:
"The 'foo' object makes the dependencies of useMemo Hook (at line 6) change on every render. " +
"Move it inside the useMemo callback. Alternatively, wrap the construction of 'foo' in its own useMemo() Hook.",
suggestions: undefined,
},
],
},
],
};

Expand Down
25 changes: 25 additions & 0 deletions packages/eslint-plugin-react-hooks/src/ExhaustiveDeps.js
Original file line number Diff line number Diff line change
Expand Up @@ -1428,6 +1428,26 @@ function getConstructionExpresionType(node) {
return 'logical expression';
}
return null;
case 'JSXFragment':
return 'JSX fragment';
case 'JSXElement':
return 'JSX element';
case 'AssignmentExpression':
if (getConstructionExpresionType(node.right) != null) {
return 'assignment expression';
}
return null;
case 'NewExpression':
return 'object construction';
case 'Literal':
if (node.value instanceof RegExp) {
return 'regular expression';
}
return null;
case 'TypeCastExpression':
return getConstructionExpresionType(node.expression);
case 'TSAsExpression':
return getConstructionExpresionType(node.expression);
}
return null;
}
Expand Down Expand Up @@ -1482,6 +1502,11 @@ function scanForConstructions({
) {
return [ref, 'function'];
}

// class Foo {}
if (node.type === 'ClassName' && node.node.type === 'ClassDeclaration') {
return [ref, 'class'];
}
return null;
})
.filter(Boolean);
Expand Down

0 comments on commit 4b6e20e

Please sign in to comment.