I'm trying to get the logout button to appear when I have a token

119 Views Asked by At
import { useState, useEffect } from "react";
import Cookies from "js-cookie";
import { NavLink } from "react-router-dom";
import BurgerMenu from "./BurgerMenu";
import { useNavigate } from "react-router-dom";

const Header = () => {
  const navigate = useNavigate();
  const [token, setToken] = useState();

  useEffect(() => {
    const token = Cookies.get("token");
    console.log(token);
    setToken(token);
  }, []);

  const handleLogout = () => {
    Cookies.remove("token");
    navigate("/login");
  };

  return (
    <>
      <BurgerMenu />
      <header className="border-[1px] border-[#FF2A70] border-transparent">
        <div className="flex sm:flex w-[full] sm:justify-around items-center py-6 p-5">
          <img src="/assets/Logo.png" alt="NightClub Logo" />
          <nav className="hidden sm:block sm:uppercase">
            <ul>
              <li className="flex gap-5 justify-between font-bold">
                <NavLink className="hover:text-[#FF2A70]" to="/">
                  Home
                </NavLink>
                <NavLink className="hover:text-[#FF2A70]" to="/blog">
                  Blog
                </NavLink>
                <NavLink className="hover:text-[#FF2A70]" to="/booking">
                  Booking
                </NavLink>
                <NavLink className="hover:text-[#FF2A70]" to="/contactus">
                  Contact us
                </NavLink>
                {token ? (
                  <button className="uppercase" onClick={handleLogout}>
                    Log out
                  </button>
                ) : (
                  <NavLink className="hover:text-[#FF2A70]" to="/login">
                    Log in
                  </NavLink>
                )}
              </li>
            </ul>
          </nav>
        </div>
      </header>
    </>
  );
};

export default Header;

Hi every one. I'm trying to get the logout button to appear when I have a token. And when I'm logged out, a login button should appear instead. At the same time, I get "undefined" displayed in the console next to Header.js:13. Anyone able to catch the problem?

1

There are 1 best solutions below

0
Scott Mitchell On

So what you can do is add the pathname from useLocation as a dependency in your useEffect, so when you go from the login page, set your cookie token and go to another page, the pathname will change and the useEffect can run to check if a token is present like such:

const navigate = useNavigate();
const { pathname } = useLocation();
const [token, setToken] = useState(null);

useEffect(() => {
  // only run this if there is no token present in the state

  if (!token) {
    const cookieToken = Cookies.get("token");
    console.log(token);
    if (cookieToken) {
      setToken(cookieToken);
    }
  }

}, [pathname]);

Also, I see you are not resetting the token state to null once you logout. Thus when you click logout, the cookie is removed, but because the token is still in the token state, the logout button will still be present and thus you will not see the login link. What you could do is the following:

const [token, setToken] = useState(null);

const handleLogout = () => {
  Cookies.remove("token");
  setToken(null);
  navigate("/login");
}; 

Initialise token to null, and set it to null once you click the logout button. This will ensure the login button appears when you have no token and the logout button is present once you have the token.

Finally, ideally you do not want to check for the token and the set the token this way in the Header component. You should check for the token in an auth wrapper component (which renders pages based on whether the user is authenticated or not), and save the login status and relevant user props in a global state, which can then be accessed by the Header component which can then render the login and log out buttons appropriately.