我们在 useEffect 中使用的所有变量都在 dependencies 数组中吗?
Are all variables we use in useEffect in dependencies array?
我知道 useEffect 的依赖项是如何工作的。但是在我的场景中,我不应该观察道具值的变化,我将它用作处理流程的条件,但如果我不将它放在依赖项数组中,我将收到 react-hooks/exhaustive-deps 警告。
我的方案是,如果 foo 和 fetchValue 发生变化,我想重新 运行 整个提取。虽然我用bar作为条件来决定调用的是fechValue,但是在我的业务逻辑中,bar的改变不应该重新运行 block.
const Component = ({ foo, bar, fetchValue }) => {
useEffect = (
() => {
if(foo) {
if (bar) {
fetchValue();
}
}
},
[foo, fetchValue] // will get a warning `react-hooks/exhaustive-deps`
)
return <div />
}
ESLint 规则用于通过 useEffect
钩子提供安全性。
如果您完全确定该值不是 useEffect
的依赖项,您可以添加注释以忽略 ESLint 规则:Disabling Rules with Inline Comments.
我建议添加 // eslint-disable-next-line
而不是 file-wide eslint-disable
。
这里是more context about this by Dan Abramov:
is there any way I can disable this rule specifically for places where the spread operator is used?
如果你认为你知道自己在做什么,你总是可以// eslint-disable-next-line react-hooks/exhaustive-deps
。
'useEffect' 中的 if 语句经常出现这样的逻辑。首先,根本不需要添加依赖项,你可以将其留空。
现在您可以做一些事情,要么忽略警告,因为您的代码看起来不错。或者重构你的代码,其中 bar
是 fetchValue()
的参数。所以你的代码是:
const Component = ({ foo, bar, fetchValue }) => {
useEffect = (
() => {
if(foo) {
fetchValue(bar);
}
},
[foo, fetchValue]
)
return <div />
}
并以 if(baz){ //your code}
开始你的 fetchValue(baz)
声明。
虽然有点麻烦。
您需要问问自己,您希望 foo 或 bar 改变的原因和位置?在组件本身内部? foo
and/or 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 />
}
你应该把你使用的所有变量放在你的 useEffects
'deps' 数组中的原因是没有这样做会由于陈旧数据而产生奇怪的问题。
例如,给定您的用例,假设您的组件 props 最初是 {foo: false, bar: false }
(假设 fetchValue
是某个固定函数),然后它们变为 {foo: true, bar: true}
。在这种情况下,您的组件将按预期调用 fetchValue
。
但是再举个例子,假设你的道具从{foo: false, bar: false}
变成了{foo: true, bar: false}
,然后又变成了{foo: true, bar: true}
。在这种情况下,fetchValue
没有触发,尽管道具与上一个示例末尾的道具相同。
也许这本身不是 "wrong",但它确实很奇怪且不直观:理想情况下,您的组件应该根据其 props 一致地运行,并且 props 更改的顺序无关紧要。
所以,是的,您始终可以 eslint-ignore
deps 数组以使其不完整,但我个人建议寻找其他解决方案。
如果没有关于用例的更多信息,很难具体说明,但也许可以记住对 fetchValue
的调用,这样如果 foo
没有改变,它就不会做任何事情?或者 foo
和 bar
可以组合成一个 prop 一起改变?
我知道 useEffect 的依赖项是如何工作的。但是在我的场景中,我不应该观察道具值的变化,我将它用作处理流程的条件,但如果我不将它放在依赖项数组中,我将收到 react-hooks/exhaustive-deps 警告。
我的方案是,如果 foo 和 fetchValue 发生变化,我想重新 运行 整个提取。虽然我用bar作为条件来决定调用的是fechValue,但是在我的业务逻辑中,bar的改变不应该重新运行 block.
const Component = ({ foo, bar, fetchValue }) => {
useEffect = (
() => {
if(foo) {
if (bar) {
fetchValue();
}
}
},
[foo, fetchValue] // will get a warning `react-hooks/exhaustive-deps`
)
return <div />
}
ESLint 规则用于通过 useEffect
钩子提供安全性。
如果您完全确定该值不是 useEffect
的依赖项,您可以添加注释以忽略 ESLint 规则:Disabling Rules with Inline Comments.
我建议添加 // eslint-disable-next-line
而不是 file-wide eslint-disable
。
这里是more context about this by Dan Abramov:
is there any way I can disable this rule specifically for places where the spread operator is used?
如果你认为你知道自己在做什么,你总是可以
// eslint-disable-next-line react-hooks/exhaustive-deps
。
'useEffect' 中的 if 语句经常出现这样的逻辑。首先,根本不需要添加依赖项,你可以将其留空。
现在您可以做一些事情,要么忽略警告,因为您的代码看起来不错。或者重构你的代码,其中 bar
是 fetchValue()
的参数。所以你的代码是:
const Component = ({ foo, bar, fetchValue }) => {
useEffect = (
() => {
if(foo) {
fetchValue(bar);
}
},
[foo, fetchValue]
)
return <div />
}
并以 if(baz){ //your code}
开始你的 fetchValue(baz)
声明。
虽然有点麻烦。
您需要问问自己,您希望 foo 或 bar 改变的原因和位置?在组件本身内部? foo
and/or 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 />
}
你应该把你使用的所有变量放在你的 useEffects
'deps' 数组中的原因是没有这样做会由于陈旧数据而产生奇怪的问题。
例如,给定您的用例,假设您的组件 props 最初是 {foo: false, bar: false }
(假设 fetchValue
是某个固定函数),然后它们变为 {foo: true, bar: true}
。在这种情况下,您的组件将按预期调用 fetchValue
。
但是再举个例子,假设你的道具从{foo: false, bar: false}
变成了{foo: true, bar: false}
,然后又变成了{foo: true, bar: true}
。在这种情况下,fetchValue
没有触发,尽管道具与上一个示例末尾的道具相同。
也许这本身不是 "wrong",但它确实很奇怪且不直观:理想情况下,您的组件应该根据其 props 一致地运行,并且 props 更改的顺序无关紧要。
所以,是的,您始终可以 eslint-ignore
deps 数组以使其不完整,但我个人建议寻找其他解决方案。
如果没有关于用例的更多信息,很难具体说明,但也许可以记住对 fetchValue
的调用,这样如果 foo
没有改变,它就不会做任何事情?或者 foo
和 bar
可以组合成一个 prop 一起改变?