【问题标题】:React Hook useEffect has a missing dependency: 'handleLogout'. Either include it or remove the dependency array reactReact Hook useEffect 缺少一个依赖项:'handleLogout'。要么包含它,要么移除依赖数组 react
【发布时间】:2022-01-09 10:09:19
【问题描述】:
import { useState, useEffect } from "react";
import LoginModal from "./LoginModal";
import { NavLink, useLocation, useNavigate } from "react-router-dom";
import { useDispatch } from "react-redux";
import { userLogout } from "../Features/User/userSlice";
import decode from "jwt-decode";

const Header = ({ toggleModalShow, showModal }) => {

  const [burgerAnimation, setBurgerAnimation] = useState(false);
  const [user, setUser] = useState();
  const location = useLocation();
  const dispatch = useDispatch();
  const navigate = useNavigate();

  // for showing login/sign up modal
  const showModalButton = () => {
    toggleModalShow();
  };

  const handleBurgerAnimation = () => {
    setBurgerAnimation(!burgerAnimation);
  };

  const handleLogout = async (id) => {
    await dispatch(userLogout({ id, navigate, dispatch }));
    setUser(null);
  };

  const burgerListItemAnimation = ...
  const burgerIconAnimation = ...

  const guestHeader = (
    <ul>
       ...
    </ul>
  );

  const userHeader = (
    <ul>
       ...
    </ul>
  );

  useEffect(() => {
    if (localStorage.getItem("user") && !user) {
      setUser(JSON.parse(localStorage.getItem("user")));
    }

    const accessToken = user?.accessToken;

    if (accessToken) {
      const decodedAccessToken = decode(accessToken);

      if(decodedAccessToken.exp * 1000 < new Date().getTime()){
        handleLogout(user.user._id);
      }
      console.log(decodedAccessToken);
    }
  }, [location, user]);

  return (
    <header className="header">
        ...
    </header>
  );
};

export default Header;

大家好。我只是想在到期日期结束时尝试注销用户。如果我将 'handleLogout' 放入 useEffect 依赖项警告不会改变。为什么我会收到此警告?如果我不解决这个问题,我会收到什么样的警告?最后,如果您有时间查看 repo,您​​会提供反馈吗?

回购:https://github.com/UmutPalabiyik/mook

【问题讨论】:

标签: javascript reactjs react-hooks use-effect redux-toolkit


【解决方案1】:

如果您将handleLogout 保留在useEffect 挂钩之外,则应该将其列为依赖项,因为它在挂钩的回调中被引用。

如果我把 handleLogout 放到 useEffect 依赖警告不会 改变。

我怀疑警告是否相同。在这一点上,我希望您看到警告更改为“依赖handleLogout 在每个渲染周期都重新声明,或者将其移动到useEffect 挂钩或使用useCallback 进行记忆...”之类的东西效果。

从这里你有 2 个选项。

  1. handleLogout 移至useEffect,使其不再是外部依赖项。

    useEffect(() => {
      const handleLogout = async (id) => {
        await dispatch(userLogout({ id, navigate, dispatch }));
        setUser(null);
      };
    
      if (localStorage.getItem("user") && !user) {
        setUser(JSON.parse(localStorage.getItem("user")));
      }
    
      const accessToken = user?.accessToken;
    
      if (accessToken) {
        const decodedAccessToken = decode(accessToken);
    
        if (decodedAccessToken.exp * 1000 < new Date().getTime()) {
          handleLogout(user.user._id);
        }
        console.log(decodedAccessToken);
      }
    }, [location, user, id, navigate, dispatch]);
    
  2. Memoize handleLogoutuseCallback 所以它是一个稳定的引用并且将它添加到效果的依赖项中。

    const handleLogout = useCallback(async (id) => {
      await dispatch(userLogout({ id, navigate, dispatch }));
      setUser(null);
    }, [id, navigate, dispatch]);
    

    ...

    useEffect(() => {
      if (localStorage.getItem("user") && !user) {
        setUser(JSON.parse(localStorage.getItem("user")));
      }
    
      const accessToken = user?.accessToken;
    
      if (accessToken) {
        const decodedAccessToken = decode(accessToken);
    
        if (decodedAccessToken.exp * 1000 < new Date().getTime()) {
          handleLogout(user.user._id);
        }
        console.log(decodedAccessToken);
      }
    }, [location, user, handleLogout]);
    

【讨论】:

  • 是的,很抱歉,如果我将 handleLogout 置于 useEffect 依赖项中,我会得到“‘handleLogout’函数使 useEffect Hook(第 112 行)的依赖项在每次渲染时都会发生变化。要解决这个问题,请将 'handleLogout' 的定义包装在它自己的 useCallback() Hook ...'中
猜你喜欢
  • 2021-07-15
  • 2021-12-06
  • 2020-06-09
  • 2021-10-31
  • 2020-06-18
  • 2021-10-21
  • 1970-01-01
  • 1970-01-01
  • 2021-02-28
相关资源
最近更新 更多