Home > database >  React Hook useEffect has a missing dependency: 'handleLogout'. Either include it or remove
React Hook useEffect has a missing dependency: 'handleLogout'. Either include it or remove

Time:12-03

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;

Hi all.I just wanted to try to log out the user when the expiration date is over. If i put 'handleLogout' to useEffect dependicies warning doesnt change. Why am i getting this warning ? What kind of warning may i get if i dont fix that ? And finally, if you have time to review the repo, would you give feedback ?

repo : https://github.com/UmutPalabiyik/mook

CodePudding user response:

If you keep handleLogout external to the useEffect hook it should be listed as a dependency as it is referenced within the hook's callback.

If i put handleLogout to useEffect dependencies warning doesn't change.

I doubt the warning is the same. At this point I would expect to you to see the warning change to something like "the dependency handleLogout is redeclared each render cycle, either move it into the useEffect hook or memoize with useCallback..." something to that effect.

From here you've the 2 options.

  1. Move handleLogout into the useEffect so it is no longer an external dependency.

    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 handleLogout with useCallback so it's a stable reference and add it to the effect's dependencies.

    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]);
    
  • Related