Home > Mobile >  how to use a function from a context inside a nav bar?
how to use a function from a context inside a nav bar?

Time:01-01

I have a user authenticated context, it has a logout function as well. I want to create a link on my nav bar that will just run the logout function, then after, redirect to the home page. However, i am getting an error saying Typerror: logout is not a function enter image description here

What I want to achieve: I want to click logout on the nav bar, it updates the state of the user to null, then send me back to the home page.

Also, how do i correctly put it into the href ?

this is what i have in my nav

import Link from "next/link";
import navStyles from "../styles/Nav.module.css";
import AccountMenu from "../components/AccountMenu.js";
import { useEffect } from "react";
import { useAuth } from "./contexts/userContext";
import { useRouter } from "next/router";
import { auth } from "./firebase";
const Nav = () => {
  const { logout } = useAuth();
  const router = useRouter();

  useEffect(() => {
    logout;
  }, []);

  const handloLogout = async () => {
    try {
      await logout();
      router.push("/");
    } catch (err) {
      alert(err);
    }
  };

  return (
    <nav className={navStyles.nav}>
      <ul>
        <li>
          <Link href="/">
            <a>
              <img className={navStyles.logo} src="/blue.png" />
            </a>
          </Link>
        </li>
        <li>
          <Link href="/Properties">
            <a>Properties</a>
          </Link>
        </li>

        <li>
          <Link href="/Login">
            <a>Login</a>
          </Link>
        </li>
        <li>
          <div>
            {/* <Link href={logout()}>
              <a>Logout</a>
            </Link> */}
            <button onClick={handloLogout}>Logout</button>
          </div>
        </li>
      </ul>
      <ul style={{ margin: "0px", padding: "0px" }}>
        <li>
          <Link href="/Signup">
            <a>Signup</a>
          </Link>
        </li>
        <li>
          <AccountMenu className={navStyles.pfp} />
        </li>
      </ul>
    </nav>
  );
};
export default Nav;

And this is part of the use context, the login unction works on the login page just fine

 import {
  createUserWithEmailAndPassword,
  onAuthStateChanged,
  signInWithEmailAndPassword,
} from "firebase/auth";
import { createContext, useContext, useEffect, useState } from "react";
import { auth } from "../firebase";

const authUserContext = createContext({});

export const AuthUserProvider = ({ children }) => {
  const [user, setUser] = useState();
  const [loading, setLoading] = useState();

  useEffect(() => {
    const unsub = onAuthStateChanged(auth, (user) => {
      if (user) {
        setUser({
          uid: user.uid,
          email: user.email,
          displayName: user.displayName,
        });
        console.log("user info set "   user.email);
      }
      setLoading(false);
    });
    return unsub;
  }, []);

  const signup = (email, password) => {
    return createUserWithEmailAndPassword(auth, email, password);
  };

  const login = (email, password) => {
    return signInWithEmailAndPassword(auth, email, password);
  };

  const logout = async () => {
    setUser(null);
    await auth.signOut();
  };

  return (
    <authUserContext.Provider value={{ user, login, signup, logout }}>
      {loading ? null : children}
    </authUserContext.Provider>
  );
};

export const useAuth = () => useContext(authUserContext);

CodePudding user response:

Here's a basic setup/guide that will help you get started:

// Use the 'useNavigate' hook to programmatically navigate to another page
import { useNavigate } from "react-router-dom";

// Grab the logout function from the Context
const { logout } = useAuth();

// Instantiate the useNavigate hook to get a method that will
// be called in order to navigate to another page
const navigate = useNavigate();

async function handleLogout() {
  await logout(); // <= Wait for the logout
  navigate("/home"); // <= programmatically navigate to the home page
}

return (
  <li>
    {/* No need for a Link or href here. Just a normal HTML element with a click handler */}
    <div onClick={handleLogout}>Logout</div>
  </li>
)
  • The href Link prop is meant for paths/routes not functions (unless these functions return a path/route)
  • In order for the Nav Component to be able to access the logout value from the Context, it must be placed inside the Context Provider.
  • Related