问题
Assume you are using React and you are writing a custom hook useSomething
that returns the identical same thing each time it is invoked for the same component.
const something = useSomething()
// useSomething() at time X === useSomething() at time Y
If you now use this something
value inside of a useEffect(() => ...)
and you do not pass something
as a dependency to the array of the second argument of useEffect
then the linter will warn you:
React Hook useEffect has a missing dependency: 'something'. Either include it or remove the dependency array. (react-hooks/exhaustive-deps)
Of course ESLint cannot know that something
will always stay identical (per component), but adding not-changing things like something
to the dependency array of useEffect
each time they are used is really annoying. Just deactivating react-hooks/exhaustive-deps
does also not seem to be a good solution (nor using // eslint-disable-next-line react-hooks/exhaustive-deps
).
Is there a better solution than to add things like that unnecessarily to the dependency array of useEffect
just to make the Linter happy?
Please find a simple demo here: https://codesandbox.io/s/sad-kowalevski-yfxcn [Edit: Please be aware that the problem is about the general pattern described above and not about this stupid little demo - the purpose of this demo is just to show the ESLint warning, nothing else]
[Edit] Please find an additional demo here: https://codesandbox.io/s/vibrant-tree-0cyn1
回答1:
Here
https://github.com/facebook/react/issues/14920#issuecomment-471070149
for example you can read this:
If it truly is constant then specifying it in deps doesn't hurt. Such as the case where a setState function inside a custom Hook gets returned to your component, and then you call it from an effect. The lint rule isn't smart enough to understand indirection like this. But on the other hand, anyone can wrap that callback later before returning, and possibly reference another prop or state inside it. Then it won’t be constant! And if you fail to handle those changes, you’ll have nasty stale prop/state bugs. So specifying it is a better default.
So maybe just adding that never-changing values to the dependency array of useEffect
may yet be the best solution. Nevertheless I hoped there would be something like a ESLint react-hooks configuration possibility to define a list of hook names which whose return values should be considered as static.
回答2:
The example is a little contrived but I suspect you may wish to create a new useEffect
block without this dependency.
If the store is not changing though I'd question why you'd wish to console log it time. If you wish to log it only on change then you'd add someStore
to your dependency array. It really depends on what you're trying to achieve and your seperation of concerns.
I'd argue that if someStore
is used as part of whatever logic is handled in this effect then it does belong in your dependency array.
You could also alternatively move const something = useSomething()
into your effect and extract it as a custom hook link
useEffect(() => {
console.log("Current state (may change)", someState);
}, [someState]);
useEffect(() => {
console.log("Current store (will never change)", someStore);
});
来源:https://stackoverflow.com/questions/58038252/react-eslint-eslint-plugin-react-hooks-shows-incorrect-missing-dependency