React钩子掉毛:总是有意义吗?

时间:2019-05-18 20:48:12

标签: reactjs eslint react-hooks

您可能已经知道,create-react-app 3附带了一条新的附加规则:react-hooks/exhaustive-deps。当挂钩的依赖项数组中缺少依赖项时,将显示警告。但这似乎并不总是合情合理。

某些依赖项可能是“沉默”或“弱”依赖项。

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

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

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

  return (...)
}

这给了我:

  

第98行:React Hook useLayoutEffect缺少依赖项:   'id','openProject','openProjects'和   'setProjectTab'。包括它们或删除依赖项数组   反应钩/详尽的下降

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

但是openProjects是我的全局状态下的数组,就像在redux中一样:每次更新时,都会创建一个新数组。

但是,该更新恰好是作为效果发生的,如果我将其添加为依赖项,则会创建一个无限的更新循环。

所以:

  • 遵循linter规则:无限循环。
  • 不遵守林特规则:令人讨厌的警告。

我是我的设计错了还是exhaustive-deps过于严格,应该考虑依赖项的概念(即不要触发效果)更改)?

2 个答案:

答案 0 :(得分:1)

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

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

答案 1 :(得分:1)

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

const isFound = find(openProjects, { id })

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

我建议保持eslint规则启用,并仔细考虑所有可能影响代码执行结果的所有依赖项的最小集合