Skip to content

Commit

Permalink
[ESLint] Check deps when callback body is outside the Hook call, too (#…
Browse files Browse the repository at this point in the history
…18435)

* Refactor: visit CallExpression

Instead of visiting the functions and looking up to see if they're in a Hook call, visit Hook calls and look down to see if there's a callback inside. I will need this refactor so I can visit functions declared outside the call.

* Check deps when callback body is outside the Hook call

* Handle the unknown case
  • Loading branch information
gaearon authored Mar 31, 2020
1 parent bf30e37 commit da54641
Show file tree
Hide file tree
Showing 2 changed files with 462 additions and 28 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,104 @@ const tests = {
}
`,
},
{
code: normalizeIndent`
function MyComponent() {
const myEffect = () => {
// Doesn't use anything
};
useEffect(myEffect, []);
}
`,
},
{
code: normalizeIndent`
const local = {};
function MyComponent() {
const myEffect = () => {
console.log(local);
};
useEffect(myEffect, []);
}
`,
},
{
code: normalizeIndent`
const local = {};
function MyComponent() {
function myEffect() {
console.log(local);
}
useEffect(myEffect, []);
}
`,
},
{
code: normalizeIndent`
function MyComponent() {
const local = {};
function myEffect() {
console.log(local);
}
useEffect(myEffect, [local]);
}
`,
},
{
code: normalizeIndent`
function MyComponent() {
function myEffect() {
console.log(global);
}
useEffect(myEffect, []);
}
`,
},
{
code: normalizeIndent`
const local = {};
function MyComponent() {
const myEffect = () => {
otherThing()
}
const otherThing = () => {
console.log(local);
}
useEffect(myEffect, []);
}
`,
},
{
// Valid because even though we don't inspect the function itself,
// at least it's passed as a dependency.
code: normalizeIndent`
function MyComponent({delay}) {
const local = {};
const myEffect = debounce(() => {
console.log(local);
}, delay);
useEffect(myEffect, [myEffect]);
}
`,
},
{
code: normalizeIndent`
let local = {};
function myEffect() {
console.log(local);
}
function MyComponent() {
useEffect(myEffect, []);
}
`,
},
{
code: normalizeIndent`
function MyComponent({myEffect}) {
useEffect(myEffect, [myEffect]);
}
`,
},
{
code: normalizeIndent`
function MyComponent(props) {
Expand Down Expand Up @@ -5998,6 +6096,246 @@ const tests = {
},
],
},
{
code: normalizeIndent`
function MyComponent() {
const local = {};
function myEffect() {
console.log(local);
}
useEffect(myEffect, []);
}
`,
errors: [
{
message:
"React Hook useEffect has a missing dependency: 'local'. " +
'Either include it or remove the dependency array.',
suggestions: [
{
desc: 'Update the dependencies array to be: [local]',
output: normalizeIndent`
function MyComponent() {
const local = {};
function myEffect() {
console.log(local);
}
useEffect(myEffect, [local]);
}
`,
},
],
},
],
},
{
code: normalizeIndent`
function MyComponent() {
const local = {};
const myEffect = () => {
console.log(local);
};
useEffect(myEffect, []);
}
`,
errors: [
{
message:
"React Hook useEffect has a missing dependency: 'local'. " +
'Either include it or remove the dependency array.',
suggestions: [
{
desc: 'Update the dependencies array to be: [local]',
output: normalizeIndent`
function MyComponent() {
const local = {};
const myEffect = () => {
console.log(local);
};
useEffect(myEffect, [local]);
}
`,
},
],
},
],
},
{
code: normalizeIndent`
function MyComponent() {
const local = {};
const myEffect = function() {
console.log(local);
};
useEffect(myEffect, []);
}
`,
errors: [
{
message:
"React Hook useEffect has a missing dependency: 'local'. " +
'Either include it or remove the dependency array.',
suggestions: [
{
desc: 'Update the dependencies array to be: [local]',
output: normalizeIndent`
function MyComponent() {
const local = {};
const myEffect = function() {
console.log(local);
};
useEffect(myEffect, [local]);
}
`,
},
],
},
],
},
{
code: normalizeIndent`
function MyComponent() {
const local = {};
const myEffect = () => {
otherThing();
};
const otherThing = () => {
console.log(local);
};
useEffect(myEffect, []);
}
`,
errors: [
{
message:
"React Hook useEffect has a missing dependency: 'otherThing'. " +
'Either include it or remove the dependency array.',
suggestions: [
{
desc: 'Update the dependencies array to be: [otherThing]',
output: normalizeIndent`
function MyComponent() {
const local = {};
const myEffect = () => {
otherThing();
};
const otherThing = () => {
console.log(local);
};
useEffect(myEffect, [otherThing]);
}
`,
},
],
},
],
},
{
code: normalizeIndent`
function MyComponent() {
const local = {};
const myEffect = debounce(() => {
console.log(local);
}, delay);
useEffect(myEffect, []);
}
`,
errors: [
{
message:
"React Hook useEffect has a missing dependency: 'myEffect'. " +
'Either include it or remove the dependency array.',
suggestions: [
{
desc: 'Update the dependencies array to be: [myEffect]',
output: normalizeIndent`
function MyComponent() {
const local = {};
const myEffect = debounce(() => {
console.log(local);
}, delay);
useEffect(myEffect, [myEffect]);
}
`,
},
],
},
],
},
{
code: normalizeIndent`
function MyComponent() {
const local = {};
const myEffect = debounce(() => {
console.log(local);
}, delay);
useEffect(myEffect, [local]);
}
`,
errors: [
{
message:
"React Hook useEffect has a missing dependency: 'myEffect'. " +
'Either include it or remove the dependency array.',
suggestions: [
{
desc: 'Update the dependencies array to be: [myEffect]',
output: normalizeIndent`
function MyComponent() {
const local = {};
const myEffect = debounce(() => {
console.log(local);
}, delay);
useEffect(myEffect, [myEffect]);
}
`,
},
],
},
],
},
{
code: normalizeIndent`
function MyComponent({myEffect}) {
useEffect(myEffect, []);
}
`,
errors: [
{
message:
"React Hook useEffect has a missing dependency: 'myEffect'. " +
'Either include it or remove the dependency array.',
suggestions: [
{
desc: 'Update the dependencies array to be: [myEffect]',
output: normalizeIndent`
function MyComponent({myEffect}) {
useEffect(myEffect, [myEffect]);
}
`,
},
],
},
],
},
{
code: normalizeIndent`
function MyComponent() {
const local = {};
useEffect(debounce(() => {
console.log(local);
}, delay), []);
}
`,
errors: [
{
message:
'React Hook useEffect received a function whose dependencies ' +
'are unknown. Pass an inline function instead.',
suggestions: [],
},
],
},
],
};

Expand Down
Loading

0 comments on commit da54641

Please sign in to comment.