React,ESLint:eslint-plugin-react-hooks 显示不正确的“缺少依赖项”

IT技术 reactjs eslint react-hooks
2021-05-02 12:28:56

假设您正在使用 React 并且您正在编写一个自定义钩子useSomething,该钩子每次为同一组件调用时都返回相同的内容。

const something = useSomething()

// useSomething() at time X  === useSomething() at time Y

如果您现在something在 a 中使用此值,useEffect(() => ...)并且没有将其something作为依赖项传递给第二个参数的数组,useEffect则 linter 将警告您:

React Hook useEffect 缺少一个依赖项:'something'。包括它或删除依赖项数组。(react-hooks/详尽的deps)

当然,ESLint 不知道它something会始终保持相同(每个组件),但是somethinguseEffect每次使用它们时向依赖数组添加不变的东西真的很烦人。仅停用react-hooks/exhaustive-deps似乎也不是一个好的解决方案(也不使用// eslint-disable-next-line react-hooks/exhaustive-deps)。

有没有更好的解决方案,而不是useEffect为了让 Linter 开心而将类似的东西不必要地添加到依赖数组中

请在这里找到一个简单的演示:https : //codesandbox.io/s/sad-kowalevski-yfxcn [编辑:请注意,问题是关于上面描述的一般模式而不是关于这个愚蠢的小演示 ​​- 这个的目的demo 只是为了显示 ESLint 警告,没有别的]

[编辑] 请在这里找到额外的演示:https : //codesandbox.io/s/vibrant-tree-0cyn1

2个回答

这里

https://github.com/facebook/react/issues/14920#issuecomment-471070149

例如,您可以阅读以下内容:

如果它确实是恒定的,那么在 deps 中指定它不会有什么坏处。例如自定义 Hook 中的 setState 函数返回到您的组件,然后您从效果中调用它的情况。lint 规则不够聪明,无法理解这样的间接性。但另一方面,任何人都可以稍后在返回之前包装该回调,并可能在其中引用另一个 prop 或 state。那么它就不会是恒定的!如果你不能处理这些变化,你就会遇到令人讨厌的陈旧的 prop/state 错误。所以指定它是一个更好的默认值。

所以也许只是将永不改变的值添加到依赖数组中useEffect可能是最好的解决方案。尽管如此,我希望有类似 ESLint react-hooks 配置的可能性来定义一个钩子名称列表,其返回值应被视为静态。

这个例子有点做作,但我怀疑你可能希望创建一个useEffect没有这种依赖性的新块。

如果商店没有改变,我会质疑你为什么希望控制台记录它的时间。如果您只想在更改时记录它,那么您将添加someStore到您的依赖项数组中。这实际上取决于您想要实现的目标以及您关注的问题。

我认为,如果someStore用作此效果中处理的任何逻辑的一部分,那么它确实属于您的依赖项数组。

您也可以选择const something = useSomething()进入效果并将其提取为自定义挂钩链接

useEffect(() => {
    console.log("Current state (may change)", someState);

  }, [someState]); 

useEffect(() => {
    console.log("Current store (will never change)", someStore);
  });