首页 > 解决方案 > React.useEffect:尽管来自 ESLint(react-hooks/exhaustive-deps)的警告,组件在依赖数组中使用 window.location.pathname 重新渲染

问题描述

我有一个左侧菜单,其中包含需要根据当前 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)

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

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

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

标签: reactjsreact-routereslint

解决方案


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

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

const location = useLocation();
useEffect(() => {
  if(location.pathname === "/events/list") {
...

推荐阅读