Fix ESLint rule crash (#15044)
Dan Abramov committed
Mar 7, 2019 at 00:39 UTC
6d2666bab16ee8c822e848f84a6feb0d42a6d78c
2 files changed
+48
-1
packages/eslint-plugin-react-hooks/__tests__/ESLintRuleExhaustiveDeps-test.js
+37
@@ -838,6 +838,17 @@ const tests = {
838
}
839
`,
840
},
841
+ {
842
+ // Regression test for a crash
843
+ code: `
844
+ function Podcasts() {
845
+ useEffect(() => {
846
+ setPodcasts([]);
847
+ }, []);
848
+ let [podcasts, setPodcasts] = useState(null);
849
+ }
850
+ `,
851
+ },
852
],
853
invalid: [
854
{
@@ -3812,6 +3823,32 @@ const tests = {
3823
'Either include it or remove the dependency array.',
3824
],
3825
},
3826
+ {
3827
+ // Regression test for a crash
3828
+ code: `
3829
+ function Podcasts() {
3830
+ useEffect(() => {
3831
+ alert(podcasts);
3832
+ }, []);
3833
+ let [podcasts, setPodcasts] = useState(null);
3834
+ }
3835
+ `,
3836
+ // Note: this autofix is shady because
3837
+ // the variable is used before declaration.
3838
+ // TODO: Maybe we can catch those fixes and not autofix.
3839
+ output: `
3840
+ function Podcasts() {
3841
+ useEffect(() => {
3842
+ alert(podcasts);
3843
+ }, [podcasts]);
3844
+ let [podcasts, setPodcasts] = useState(null);
3845
+ }
3846
+ `,
3847
+ errors: [
3848
+ `React Hook useEffect has a missing dependency: 'podcasts'. ` +
3849
+ `Either include it or remove the dependency array.`,
3850
+ ],
3851
+ },
3852
],
3853
};
3854
packages/eslint-plugin-react-hooks/src/ExhaustiveDeps.js
+11
-1
@@ -164,7 +164,17 @@ export default {
164
}
165
// Detect primitive constants
166
// const foo = 42
167
- const declaration = def.node.parent;
167
+ let declaration = def.node.parent;
168
+ if (declaration == null) {
169
+ // This might happen if variable is declared after the callback.
170
+ // In that case ESLint won't set up .parent refs.
171
+ // So we'll set them up manually.
172
+ fastFindReferenceWithParent(componentScope.block, def.node.id);
173
+ declaration = def.node.parent;
174
+ if (declaration == null) {
175
+ return false;
176
+ }
177
+ }
178
if (
179
declaration.kind === 'const' &&
180
init.type === 'Literal' &&