My webpage requires to reload every time to update user state.
As to the problem, in the handleLogin func, the page should be redirected to homepage (‘/’) and refresh itself, so that the user state is updated, due to AuthContextProvider Component checking onAuthStateChanged. However, it can only either reload the page, or redirect to homepage (which I manually need to refresh). So please help me with some ideas to this one.
I am thinking of doing global.this to add a boolean which handleLogin can access locally How to declare a global variable in React?.
And since most of these are client components, so far only router.push can redirect between pages.
src/app/login/page.jsx
'use client';
import Link from "next/link";
import "../../components/auth";
import { useState } from "react";
import { auth } from "../../components/auth";
import { signInWithEmailAndPassword } from "firebase/auth";
import { useRouter } from "next/navigation";
import { redirect } from "next/navigation";
//SOME CONDITIONALS VALID_EMAIL AND VALID_PASSWORD
export default function loginPage() {
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const router = useRouter();
//*EVENT
const handleLogin = async (e) => {
e.preventDefault();
if (valid_email(email) && valid_password(password)) {
signInWithEmailAndPassword(auth, email, password)
.then((res) => {
console.log({ res });
router.push('/'); //WORKAROUND?
document.reload(); //WORKAROUND?
})
.catch((e) => console.error(e));
}
}
// RETURN SOME RENDERING
src/components/authContext.jsx
'use client'
import React from 'react';
import { onAuthStateChanged} from 'firebase/auth';
import { auth } from "../components/auth"
import { useRouter } from 'next/navigation';
export const AuthContext = React.createContext({});
export const useAuthContext = () => React.useContext(AuthContext);
const AuthContextProvider = ({
children,
}) => {
const [user, setUser] = React.useState(null);
const [loading, setLoading] = React.useState(true);
const [redirect, setRedirect] = React.useState(false);
const router = useRouter();
React.useEffect(() => {
const unsubscribe = onAuthStateChanged(auth, (user) => {
if (user) {
setUser(user);
if (redirect) location.reload();
} else {
setUser(null);
if (redirect) location.reload();
}
setRedirect(false);
setLoading(false);
});
return () => unsubscribe();
}, []);
return (
<AuthContext.Provider value={{ user }}>
{loading ? <div>Loading...</div> : children}
</AuthContext.Provider>
);
};
export default AuthContextProvider;
2
Answers
Using
router.push(redirectUrl ?? '/');
is a common pattern for this, especially if a user has been directed to the login page after trying to access an auth-protected route, they can then be redirected back to the page they were originally browsing.First of all move the handleLogin to the AuthContext and use from there only by either
useContext
or you can create a hookuseAuth
for that.if the error persist then use
useEffect
to push to "/" after the state changes not in the handleLogin func.Here’s an example