The signInWithEmailAndPassword appears to be an async function and your code isn't waiting for the returned Promise to resolve. I'm guessing you are seeing the navigate("/"); called and the app is navigating to the home page.
const handleLogIn = (e) => {
e.preventDefault();
const email = e.target.email.value;
const password = e.target.password.value;
signInWithEmailAndPassword(email, password); // <-- no waiting for promise
e.target.reset();
navigate(from, { replace: true }); // <-- navigate away
};
useSignInWithEmailAndPassword
export default (auth: Auth): EmailAndPasswordActionHook => {
const [error, setError] = useState<AuthError>();
const [loggedInUser, setLoggedInUser] = useState<UserCredential>();
const [loading, setLoading] = useState<boolean>(false);
const signInWithEmailAndPassword = async (
email: string,
password: string
) => {
setLoading(true);
setError(undefined);
try {
const user = await firebaseSignInWithEmailAndPassword(
auth,
email,
password
);
setLoggedInUser(user);
} catch (err) {
setError(err as AuthError);
} finally {
setLoading(false);
}
};
const resArray: EmailAndPasswordActionHook = [
signInWithEmailAndPassword,
loggedInUser,
loading,
error,
];
return useMemo<EmailAndPasswordActionHook>(() => resArray, resArray);
};
The handleLogin handler should probably wait for the Promise to settle so any errors can be returned by the hook. It turns out though that signInWithEmailAndPassword also doesn't return any resolve/rejected values, so there's no way to know the authentication was successful from within the handleLogIn callback function, the component will need to use the hook's returned loading and loggedInUser states to determine if it is safe to navigate.
Example:
const Login = () => {
const [
signInWithEmailAndPassword,
loggedInUser,
loading,
error,
] = useSignInWithEmailAndPassword(auth);
const location = useLocation();
const navigate = useNavigate();
const from = location?.state?.from?.pathname || '/';
useEffect(() => {
if (!loading && loggedInUser) {
navigate(from, { replace: true });
}, [loggedInUser, loading, navigate, from]);
if (error) {
return (
<div>
<p>Error: {error.message}</p>
</div>
);
}
const handleLogIn = (e) => {
e.preventDefault();
const email = e.target.email.value;
const password = e.target.password.value;
signInWithEmailAndPassword(email, password)
e.target.reset();
}
...