[英]React, ESLint: eslint-plugin-react-hooks shows incorrect “missing dependency”
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.假设您正在使用 React,并且您正在编写一个自定义钩子useSomething
,它每次为同一个组件调用它时都会返回相同的东西。
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:如果你现在在useEffect(() =>...)
中使用这个something
值,并且你没有将something
作为依赖传递给 useEffect 的第二个参数的数组,那么useEffect
会警告你:
React Hook useEffect has a missing dependency: 'something'. React Hook useEffect 缺少依赖项:'something'。 Either include it or remove the dependency array.包括它或删除依赖数组。 (react-hooks/exhaustive-deps) (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.当然,ESLint 无法知道something
会始终保持不变(每个组件),但是每次使用它们时将不变的something
添加到useEffect
的依赖数组中确实很烦人。 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
).仅仅停用react-hooks/exhaustive-deps
似乎也不是一个好的解决方案(也不使用// 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?有没有更好的解决方案,而不是为了让 Linter 开心而不必要地向useEffect
的依赖数组中添加类似的东西?
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]请在这里找到一个简单的演示: https://codesandbox.io/s/sad-kowalevski-yfxcn演示只是为了显示 ESLint 警告,仅此而已]
[Edit] Please find an additional demo here: https://codesandbox.io/s/vibrant-tree-0cyn1 [编辑] 请在此处找到其他演示: https://codesandbox.io/s/vibrant-tree-0cyn1
Here这里
https://github.com/facebook/react/issues/14920#issuecomment-471070149 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.如果它确实是恒定的,那么在 deps 中指定它并没有什么坏处。 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.例如,自定义 Hook 中的 setState function 被返回到您的组件,然后您从效果中调用它。 The lint rule isn't smart enough to understand indirection like this. lint 规则不够聪明,无法理解这样的间接性。 But on the other hand, anyone can wrap that callback later before returning, and possibly reference another prop or state inside it.但另一方面,任何人都可以在返回之前包装该回调,并可能在其中引用另一个道具或 state。 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.所以也许只是将永不改变的值添加到useEffect
的依赖数组中可能是最好的解决方案。 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.尽管如此,我希望有类似 ESLint react-hooks 配置的可能性来定义一个钩子名称列表,其返回值应被视为 static。
The example is a little contrived but I suspect you may wish to create a new useEffect
block without this dependency.这个例子有点做作,但我怀疑你可能希望创建一个没有这种依赖关系的新useEffect
块。
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.如果您希望仅在更改时记录它,那么您可以将someStore
添加到您的依赖项数组中。 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.我认为如果someStore
用作在此效果中处理的任何逻辑的一部分,那么它确实属于您的依赖项数组。
You could also alternatively move const something = useSomething()
into your effect and extract it as a custom hook link您也可以将const something = useSomething()
移动到您的效果中并将其提取为自定义挂钩链接
useEffect(() => {
console.log("Current state (may change)", someState);
}, [someState]);
useEffect(() => {
console.log("Current store (will never change)", someStore);
});
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.