您可能已经知道,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'。包括它们或删除依赖项数组 反应钩/详尽的下降
openProject
和setProjectTab
是常量函数,它们始终指向相同的引用,因此我可以将它们包含在数组中以缩短警告。没问题。
但是openProjects
是我的全局状态下的数组,就像在redux中一样:每次更新时,都会创建一个新数组。
但是,该更新恰好是作为效果发生的,如果我将其添加为依赖项,则会创建一个无限的更新循环。
所以:
我是我的设计错了还是exhaustive-deps
过于严格,应该考虑弱依赖项的概念(即不要触发效果)更改)?
答案 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规则启用,并仔细考虑所有可能影响代码执行结果的所有依赖项的最小集合。