我知道useEffect的依赖项如何工作。但是在我的场景中,我不应该看我将prop值的更改用作处理流的条件,但是如果不将其放在依赖关系数组中,则会收到react-hooks / exhaustive-deps警告。
我的情况是,如果foo和fetchValue更改,我想重新运行整个提取。尽管我使用bar作为确定是否调用fechValue的条件,但是在我的业务逻辑中,更改bar不应使重新运行该块。
const Component = ({ foo, bar, fetchValue }) => {
useEffect = (
() => {
if(foo) {
if (bar) {
fetchValue();
}
}
},
[foo, fetchValue] // will get a warning `react-hooks/exhaustive-deps`
)
return <div />
}
答案 0 :(得分:1)
ESLint规则可以通过useEffect
钩提供安全性。
如果您完全确定该值不是useEffect
的依赖项,则可以添加注释以忽略ESLint规则:Disabling Rules with Inline Comments。
我建议添加// eslint-disable-next-line
而不是文件范围的eslint-disable
。
这里是more context about this by Dan Abramov:
有什么方法可以专门针对使用传播运算符的地方禁用此规则吗?
如果您认为自己知道自己在做什么,可以随时
// eslint-disable-next-line react-hooks/exhaustive-deps
。
答案 1 :(得分:1)
本应将所有使用的变量放入useEffects
'deps'数组中的原因未这样做,可能会由于数据过时而产生奇怪的问题。
例如,给定您的用例,假设您的组件prop最初是{foo: false, bar: false }
(假设fetchValue
是某个固定函数),然后变为{foo: true, bar: true}
。在这种情况下,您的组件将按预期方式调用fetchValue
。
但作为另一个示例,假设您的道具从{foo: false, bar: false}
更改为{foo: true, bar: false}
,然后更改为{foo: true, bar: true}
。在这种情况下,fetchValue
并未开火,尽管道具与上一个示例末尾的道具相同。
也许这本身并不是“错误的”,但它肯定是很奇怪和不直观的:理想情况下,组件应根据其道具保持一致的行为,并且道具的更改顺序无关紧要。
因此,是的,您始终可以eslint-ignore
的deps数组不完整,但我建议您个人寻求其他解决方案。
没有用例的更多信息就很难具体说明,但是也许可以记住对fetchValue
的调用,以便在foo
不变的情况下不做任何事情?还是foo
和bar
可以组合成一个道具,以便它们一起改变?
答案 2 :(得分:-2)
类似的逻辑经常在'useEffect'中的if语句中发生。首先,根本不需要添加依赖项,您可以将其保留为空。
现在您可以做一些事情,要么简单地忽略警告,因为您的代码看起来不错。或在bar
是fetchValue()
的参数的地方重构代码。所以你的代码应该是:
const Component = ({ foo, bar, fetchValue }) => {
useEffect = (
() => {
if(foo) {
fetchValue(bar);
}
},
[foo, fetchValue]
)
return <div />
}
然后用fetchValue(baz)
开始if(baz){ //your code}
声明。
虽然有点麻烦。
您需要问自己,为什么foo或bar会发生变化,为什么?在哪里?在组件本身内部?然后不应该将foo
和/或bar
设为foo
和或bar
作为默认值的状态?
const Component = ({ foo, bar, fetchValue }) => {
const [fooState, setFooState] = useState(foo);
const [barState, setBarState] = useState(bar);
useEffect = (
() => {
fooState && barState && fetchValue();
//does the same as your code, I just prefer short circuits for these kind of things.
},
[fooState, fetchValue()]
)
return <div />
}