React 钩子上缺少依赖性检查错误

Missing dependency linting error on React hook

我在 React 函数组件中使用 useEffect,如下所示:

useEffect(() => {
  const handleRouteChangeComplete = () => {
    window.scrollTo(0, 0);
    userInterface.dispatch(closeNavigation());
  };

  Router.events.on('routeChangeComplete', handleRouteChangeComplete);
}, []);

useEffect 上的第二个(数组)选项给出了以下 linting 错误:

React Hook useEffect has a missing dependency: 'userInterface'. Either include it or remove the dependency array. eslint(react-hooks/exhaustive-deps)

我认为 linting 错误中的任何一个选项都不正确。

我是不是遗漏了什么,还是 linting 迫使我写出不正确的逻辑?

我会在这一个实例中禁用该规则,但我的应用程序中还有 4 个其他实例出现类似错误。

eslint 错误是有原因的,这是为了防止由于陈旧的值而难以注意到错误。本质上,lint 错误只是告诉您您的 userInterface 变量将在效果中失效。

消除该错误不一定是个好主意,因为如果您添加更多依赖项,您可能不会意识到为什么事情没有像您预期的那样更新。

关于同一件事的另一个 post:

https://github.com/facebook/create-react-app/issues/6880

你应该牢记的一件重要事情是确保你清理你的动作,不管它是否只在安装时完成,因为如果你不清理,有时效果可能会超过组件的生命周期顶起来。

对于如何解决这个问题,您有几种不同的选择,如果分派是稳定的(基于名称,通常是稳定的),那么您可以从 userInterface 变量中拉出分派,然后将其添加到依赖项数组.

const { dispatch } = userInterface;

useEffect(() => {
  const handleRouteChangeComplete = () => {
    window.scrollTo(0, 0);
    dispatch(closeNavigation());
  };

  Router.events.on('routeChangeComplete', handleRouteChangeComplete);
  () => {
    Router.events.off('routeChangeComplete', handleRouteChangeComplete);
  };
}, [dispatch]);

如果提取分派值不是一个选项,那么您可以使用 ref 来确保以稳定的方式保持最新版本的 userInterface。这是一项非常常见的任务,有时您可能希望将逻辑提取到自定义挂钩中以获取值的引用。

const userInterfaceRef = useRef(userInterface);
useEffect(() => {
  userInterfaceRef.current = userInterface;
}, [userInterface]);

useEffect(() => {
  const handleRouteChangeComplete = () => {
    window.scrollTo(0, 0);
    userInterfaceRef.current.dispatch(closeNavigation());
  };

  Router.events.on('routeChangeComplete', handleRouteChangeComplete);
  () => {
    Router.events.off('routeChangeComplete', handleRouteChangeComplete);
  };
}, []);

这里看似额外的 useEffect 的原因是因为除非您确定 userInterface 永远不会改变,否则您需要使其保持最新,否则 userInterfaceRef 将过时。我之所以使用 userInterface 的 ref 而不是 dispatch 函数是因为这样你就可以在效果中使用 userInterface 的其他属性而不会出现任何问题。

如果您的效果中需要有您不想重新启动效果的依赖项,请使用我描述的 ref 选项来确保您拥有最新的值而无需重新 运行每次更改时都会生效。

如果您要在效果中强制性地向某些内容添加 on 处理程序,则应确保将其清理干净。养成好习惯。