React.useEffect:尽管来自 ESLint 的警告(react-hooks/exhaustive-deps),组件仍使用依赖项数组中的 window.location.pathname 重新渲染

Jak*_*222 2 reactjs eslint react-router

我有一个左侧菜单,其中包含需要根据当前 URL 路径选择/取消选择的子选项。在寻找解决方案的过程中,我发现以下代码给出了 ESLint 错误,如下所示:

useEffect(() => {
    if (window.location.pathname === "/events/list") {
      setManageEventsOpen(true);
      setSelectedListItem(LIST_SELECTED);
    }
    if (window.location.pathname === "/events/map") {
      setManageEventsOpen(true);
      setSelectedListItem(MAP_SELECTED);
    }
    if (window.location.pathname === "/events/calendar") {
      setManageEventsOpen(true);
      setSelectedListItem(CALENDAR_SELECTED);
    }
  }, [window.location.pathname]);

React Hook useEffect has an unnecessary dependency: 'window.location.pathname'. 
Either exclude it or remove the dependency array. 
Outer scope values like 'window.location.pathname' aren't valid 
dependencies because mutating them doesn't re-render 
the component.eslint(react-hooks/exhaustive-deps)
Run Code Online (Sandbox Code Playgroud)

但是,当我运行此代码时,我注意到当路径更改时组件会重新渲染。我认为这只是因为在手动更改 URL 并刷新页面时整个应用程序正在重新加载,但即使从另一个组件使用 History.push('/events/list') 也会导致重新渲染。

我想知道,这个警告不正确吗?有人看到不同的结果吗?

注意:我在我的应用程序中对此有更好的解决方案,但我仍然对警告感到好奇。

JBa*_*lin 5

当路径更改时您的应用程序重新呈现这一事实并不意味着警告不正确。这意味着你的useEffect逻辑依赖于不相关的逻辑,这很混乱并且容易出现错误。

相反,您应该显式侦听/订阅 - 的更改location.pathname,以便您的组件使用更新后的值重新呈现。鉴于您使用 React Router,请检查他们的useLocation挂钩:

const location = useLocation();
useEffect(() => {
  if(location.pathname === "/events/list") {
...
Run Code Online (Sandbox Code Playgroud)