useEffect 依赖数组和 ESLint 穷举-deps 规则
Posted
技术标签:
【中文标题】useEffect 依赖数组和 ESLint 穷举-deps 规则【英文标题】:useEffect dependency array and ESLint exhaustive-deps rule 【发布时间】:2019-11-20 04:22:04 【问题描述】:我有一个如下所示的组件:
const MyComponent = props =>
const checked, onChange, id = props;
const [isChecked, setChecked] = useState(false);
useEffect(() =>
onChange && onChange( isChecked: !!checked, id );
setChecked(checked);
, [checked]);
const childProps =
id,
isChecked
;
return <ChildComponent ...childProps />;
;
穷举-deps lint 规则并不令人满意:
React Hook useEffect 缺少依赖项:
id
和onChange
。 要么包含它们,要么删除依赖数组。 (react-hooks/exhaustive-deps)eslint
我知道id
和onChange
不会改变,所以将它们添加到依赖数组中似乎没有必要。但这条规则不是警告,而是明确的指示。
是 ESLint 规则:
1) 在这种情况下过于谨慎而且有点愚蠢,所以可以忽略不计?
2) 突出最佳实践 - 即尽量减少将来可能发生的意外错误,例如,如果父组件的更改意味着 id 将在将来的某个时间点发生更改?
3) 显示当前代码的实际/可能问题?
【问题讨论】:
【参考方案1】:实际上规则非常简单:要么传递一个包含所有依赖项的数组,要么不传递任何东西。所以我猜这个规则并不愚蠢,它只是不知道依赖关系是否会改变。所以是的,如果你传递一个依赖数组,它应该包含所有依赖,包括那些你知道的不会改变的事实。这样的事情会引发警告:
useEffect(() => dispatch( someAction ), [])
要解决这个问题,您应该将 dispatch
作为依赖项传递,即使它永远不会改变:
useEffect(() => dispatch( someAction ), [dispatch])
不要禁用详尽的 deps 规则,如 here 所述
2021 年 5 月 4 日更新
地址为here。这不再需要,因为 eslint pull #1950.
现在,具有稳定签名的引用类型(例如来自 useState
或 useDispatch
的那些来源)可以安全地在效果内使用而无需触发 exhaustive-deps
,即使来自 props
也是如此
【讨论】:
感谢您的链接。所以看起来它更像是2),对吧?也就是说,即使您确切地知道自己在做什么,它仍然有助于消除可能的错误和/或让您仔细考虑和构建代码。 是的!这就是要点。 关于您的示例的旁注:如果dispatch
来自对 useReducer
的调用,您可以在效果中调用它而不将其添加为依赖项,ESLint 不会抱怨它,因为它保证永远不会改变。它怎么知道这个?我想知道。
是的。这是other answer 中解决的问题。谢谢指出【参考方案2】:
看待它的方式是每个渲染都有自己的效果。如果效果与一组特定的值相同,那么我们可以告诉 React 依赖数组中的这些值。理想情况下,具有相同 state 和 props 的组件在其渲染和效果完成后将始终具有相同的输出(渲染组件 + 效果)。这就是让它对错误更有弹性的原因。
规则的要点是,如果 deps 确实发生了变化,效果应该再次运行,因为它现在是不同的效果。
这 3 个链接也提供了更多关于此的见解:
https://github.com/facebook/react/issues/14920#issuecomment-471070149 https://overreacted.io/a-complete-guide-to-useeffect/ https://overreacted.io/writing-resilient-components/【讨论】:
以上是关于useEffect 依赖数组和 ESLint 穷举-deps 规则的主要内容,如果未能解决你的问题,请参考以下文章
ESLint 希望 setSate 作为 useEffect 的依赖项,但这会导致无限循环(react-hooks/exhaustive-deps)
React Hook useEffect 缺少依赖项(没有在 useEffect 中移动函数)
useEffect exhaustive-deps 警告:这试图避免哪些可能的问题?
useEffect 在自定义钩子中使用 ref 缺少依赖项警告