React自定义useAuth Hook错误值不更新,登录失败仍跳转
问题原因分析
你遇到的问题核心有两点:
- 错误无法触发组件的异常捕获逻辑:你的
useAuth里的login函数在捕获错误后,只更新了error状态但没有把错误重新抛出。这就导致Login组件里的await login(user)不会进入catch块,不管登录成功失败,都会直接执行navigate("/dashboard")。 - 组件未利用
error状态做跳转拦截:就算组件能拿到更新后的error,当前代码也没在提交后检查这个状态来阻止错误情况下的跳转。
修复方案
第一步:修改useAuth.js,让错误可以被调用方捕获
在每个异步函数的catch块里,设置完error状态后把错误重新抛出,这样调用组件就能通过try/catch感知到错误:
import { useState } from "react"; import { account } from "../appwrite/config"; import { ID } from "appwrite"; const useAuth = () => { const [error, setError] = useState(null); const signup = async (user) => { setError(null); // 每次调用先清空旧错误 try { await account.create( ID.unique(), user.email, user.password, user.username ); } catch (error) { console.log(error); setError(error.message); throw error; // 重新抛出错误,让调用方捕获 } }; const login = async (user) => { setError(null); try { await account.createEmailSession(user.email, user.password); } catch (error) { console.log(error); setError(error.message); throw error; // 新增该行,抛出错误 } }; const logout = async () => { setError(null); try { await account.deleteSession("current"); } catch (error) { console.log(error); setError(error.message); throw error; // 保持逻辑一致性 } }; return { signup, login, logout, error }; }; export default useAuth;
第二步:修改Login.js,仅在登录成功时跳转,并显示错误信息
现在login函数会抛出错误,catch块会触发,同时我们可以把error状态显示在页面上提示用户:
import { useState } from "react"; import useAuth from "../hooks/useAuth"; import { useNavigate } from "react-router-dom"; const Login = () => { const [user, setUser] = useState({}); const { login, error } = useAuth(); const navigate = useNavigate(); const handleChange = (e) => { setUser({ ...user, [e.target.name]: e.target.value }); }; const handleSubmit = async (e) => { e.preventDefault(); try { await login(user); // 只有登录成功才执行跳转 navigate("/dashboard"); } catch (error) { console.log("登录失败:", error); } }; return ( <div> <h1>Log In</h1> {/* 新增错误提示区域 */} {error && <p style={{ color: "red", margin: "1rem 0" }}>{error}</p>} <form onSubmit={handleSubmit}> <div> <label htmlFor="email">Email</label> <input onChange={handleChange} type="email" name="email" id="email" /> </div> <div> <label htmlFor="password">Password</label> <input onChange={handleChange} type="password" name="password" id="password" /> </div> <button>Log In</button> </form> </div> ); }; export default Login;
额外说明
- 每次调用
login/signup前先调用setError(null),是为了清空上一次的错误状态,避免旧错误干扰新的操作。 - 如果你不想用
try/catch,也可以在Login组件里用useEffect监听error的变化来做提示,但用try/catch控制跳转逻辑会更直接可靠。
内容的提问来源于stack exchange,提问作者r121
相关产品推荐
相关产品推荐

