From b231b62720e99ccb60316c505932d79f3ac8b4ad Mon Sep 17 00:00:00 2001 From: XingfenD Date: Mon, 7 Sep 2026 15:32:13 +0800 Subject: [PATCH] fix(web): login honors from-path redirect; me-error clears stored token --- web/src/auth/AuthContext.tsx | 5 ++++- web/src/pages/Login.tsx | 4 +--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/web/src/auth/AuthContext.tsx b/web/src/auth/AuthContext.tsx index 2eb0be4..45068a5 100644 --- a/web/src/auth/AuthContext.tsx +++ b/web/src/auth/AuthContext.tsx @@ -26,7 +26,10 @@ export function AuthProvider({ children }: { children: ReactNode }) { const meQ = useQuery({ queryKey: ["me"], queryFn: api.me, enabled: !!token, retry: 0 }); useEffect(() => { - if (token && meQ.isError) setTok(null); + if (token && meQ.isError) { + setToken(null); // 非 401 失败也要清持久化 token,避免与 React 状态分叉导致 RequireAuth 永久加载 + setTok(null); + } }, [token, meQ.isError]); const value = useMemo( diff --git a/web/src/pages/Login.tsx b/web/src/pages/Login.tsx index fda8468..5402644 100644 --- a/web/src/pages/Login.tsx +++ b/web/src/pages/Login.tsx @@ -1,5 +1,5 @@ import { useState, type FormEvent } from "react"; -import { Navigate, useLocation, useNavigate } from "react-router-dom"; +import { Navigate, useLocation } from "react-router-dom"; import { useAuth } from "../auth/AuthContext"; import { toast } from "../components/Toaster"; import { btnPrimary, card, input } from "../components/ui"; @@ -7,7 +7,6 @@ import { btnPrimary, card, input } from "../components/ui"; export default function Login() { const { login, user } = useAuth(); const loc = useLocation() as { state?: { from?: string } }; - const nav = useNavigate(); const [u, setU] = useState(""); const [p, setP] = useState(""); const [busy, setBusy] = useState(false); @@ -19,7 +18,6 @@ export default function Login() { setBusy(true); try { await login(u, p); - nav("/", { replace: true }); } catch (err) { toast("err", err instanceof Error ? err.message : "登录失败"); } finally {