React hooks linting:它总是有意义吗?

React hooks linting : Does it always make sense?

您可能知道,create-react-app 3 附带了一个新的 eslint 规则:react-hooks/exhaustive-deps。当挂钩的依赖项数组中缺少依赖项时,会显示警告。但这似乎并不总是有意义。

一些依赖项可能是 "silent" 或 "weak" 个依赖项。

在代码中,我有以下情况:

const Project = ({ id, '*': tab }) => {
  const [{ openProjects }, { openProject, setProjectTab }] = useStore()

  useLayoutEffect(() => {
    if(find(openProjects, { id }))
      setProjectTab(id, tab)
    else openProject(id, tab)
  }, [tab])

  return (...)
}

这给了我:

Line 98: React Hook useLayoutEffect has missing dependencies: 'id', 'openProject', 'openProjects', and 'setProjectTab'. Either include them or remove the dependency array react-hooks/exhaustive-deps

openProjectsetProjectTab 是常量函数,它们总是指向相同的引用,所以我可以将它们包含在数组中以缩短警告。没问题。

但是 openProjects 是我的全局状态中的一个数组,它的处理方式与 redux 中的一样:每次有更新时,都会创建一个新数组。

但是,该更新恰好作为 效果 发生,如果我将其添加为依赖。

所以 :

我的设计是不是错了,或者 exhaustive-deps 真的太严格了,应该考虑 依赖的概念(即 不要 触发变化效果) ?

我遇到了同样的问题。当我使用钩子时,我只包含依赖数组中变化的变量,我不包含我知道不会变化的常量或数据。

您可以使用 // eslint-disable-next-line react-hooks / exhaustive-deps 禁用下一行的 linting。

如果某些效果取决于某些计算的结果,例如find(openProjects, { id }),但不基于该计算的参数,则可以使其 明确地 仅依赖于该计算的结果,例如通过提取变量:

const isFound = find(openProjects, { id })

useLayoutEffect(() => {
  if(isFound)
    setProjectTab(id, tab)
  else openProject(id, tab)
}, [isFound, setProjectTab, openProject, id, tab])

我建议保持 eslint 规则处于启用状态,并更加认真地考虑可能影响代码执行结果的所有依赖项的最小集合