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
openProject
和 setProjectTab
是常量函数,它们总是指向相同的引用,所以我可以将它们包含在数组中以缩短警告。没问题。
但是 openProjects
是我的全局状态中的一个数组,它的处理方式与 redux 中的一样:每次有更新时,都会创建一个新数组。
但是,该更新恰好作为 效果 发生,如果我将其添加为依赖。
所以 :
- 遵守 linter 规则:无限循环。
- 不遵守 linter 规则:烦人的警告。
我的设计是不是错了,或者 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 规则处于启用状态,并更加认真地考虑可能影响代码执行结果的所有依赖项的最小集合。
您可能知道,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
openProject
和 setProjectTab
是常量函数,它们总是指向相同的引用,所以我可以将它们包含在数组中以缩短警告。没问题。
但是 openProjects
是我的全局状态中的一个数组,它的处理方式与 redux 中的一样:每次有更新时,都会创建一个新数组。
但是,该更新恰好作为 效果 发生,如果我将其添加为依赖。
所以 :
- 遵守 linter 规则:无限循环。
- 不遵守 linter 规则:烦人的警告。
我的设计是不是错了,或者 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 规则处于启用状态,并更加认真地考虑可能影响代码执行结果的所有依赖项的最小集合。