最佳实践:useEffect 依赖 setState 或 dispatch,通过 useContext 或自定义钩子

时间:2021-05-07 23:04:47

标签: reactjs react-hooks use-effect use-context use-reducer

我正在研究处理 useEffect() 中依赖项数组的所有最佳实践。首先,一些指南(来自 this blog post 和其他地方):

  1. 如果您在 useEffect 中调用一个在 useEffect 中使用的函数,只需在 useEffect() 中定义它。部门不需要。
  2. 如果您在 useEffect 中调用一个在 useEffect 内和没有 useEffect 内使用的函数,但它不需要访问组件范围内的任何内容,请将其提升到组件外。部门不需要。
  3. 如果您在 useEffect 中调用函数,该函数是 useReducer() 返回的调度程序或 useState() 返回的设置程序,则不需要将其包含在依赖项中(这不会造成伤害,但是你不必这样做)。
  4. 否则,将您的函数包装在 useCallback 中并将其添加到 useEffect 的依赖项数组中。

这一切都正确吗?如果是这样,我的问题:

  1. 如果您使用 useContext 或自定义钩子获取由 useState/useReducer elsewhere 创建的 setter/dispatcher,并在 useEffect 中调用它,linter 会警告您将其添加到依赖项大批。我认为这是因为 linter 不知道该函数来自 useState/useReducer,所以它必须谨慎行事并警告你。因此,似乎最好的做法是在 deps 数组中夹住 [dispatch] 或 [setSomething]:就像上面的第 3 点一样,它不会受到伤害(它仍然表现得像一个空数组),并且做所以会满足短绒。这似乎是答案here。但是,我看到多个资源说您实际上仍然应该将它包装在 useCallback 中(即 here - 我意识到这也涉及一个不同的问题,但我确实在很多地方看到了 stableDispatch):
const [state, dispatch] = useContext(MyContext);
const stableDispatch = useCallback(dispatch, []);

useEffect(() => {
  stableDispatch(foo)
},[stableDispatch]);

然而,这似乎并没有起到任何作用。而不是 linter 警告您 useEffect 中缺少 deps,现在它只是警告您 useCallback 中缺少 deps。所以为了更简洁,我的问题是:

  • #1-4 准确吗?
  • 在 #5 的情况下,最佳实践是什么(这也解决了 linter 警告,但也不会导致不必要地运行效果)?直接把'dispatch'放在useEffect的deps里,或者用useCallback,或者有什么不同的方法?

非常感谢任何澄清。

0 个答案:

没有答案