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
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.