[WIP] Add ESLint rule for useEffect/useCallback/useMemo Hook dependencies #14048
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This is just initial work from @calebmer. We didn't end up dogfooding this yet but @jamiebuilds expressed interest in picking it up. For some reason it doesn't pass tests — maybe there's some bug in the internal diff or maybe some dependency upgrade broke it. The semantics are also not set in stone and will probably need changes. Original description by @calebmer:
This diff adds a lint to enforce reactive dependencies are provided in the second argument of
useEffect
/useCallback
. This lint is currently really strict. There are a lot of valid patterns it doesn't support. Unlike many other lints you should really be disabling this one when you want to do something more interesting then what the strict rule supports.Here's what the lint does. The lint checks that identifiers and member expressions used in a "reactive hook callback" (lint internal name only) are declared in the reactive hook's dependency list.
The lint requires that the dependency list be an array literal (no
useEffect(() => {}, dependencies)
) and that the dependency list not have spreads (nouseEffect(() => {}, [...dependencies])
). Both of these are valid forms in some interesting cases, though, but they make static analysis harder.One thought is that perhaps we could support spreading an array as satisfying a dependency. For example allow:
But I have not currently implemented this.
Some other reasonable cases (IMO) this lint does not allow include:
and:
Both these forms allow you to be a bit more precise about the memoization breaking in
useEffect
and other reactive hooks.This lint also warns about extra declarations in the dependency list:
And warns about duplicated declared dependencies:
Let me know if you think these constraints are reasonable. They might be good for 70-80% of cases and then after that there is always
// eslint-disable-line
.