React登录后Cookie未定义,需刷新页面才正常的问题求助
React登录后自定义Hook获取Token为undefined,刷新后恢复的解决方案
问题诊断
核心问题是自定义Hook未感知到登录时Cookie的更新:当前登录逻辑仅设置了Cookie和用户状态,但自定义Hook要么只在组件初始化时读取一次Cookie,要么依赖的Context未同步更新Token,导致导航到首页后Hook仍返回旧值(undefined),只有刷新页面时组件重新初始化,才会读取到最新的Cookie值。
解决方案
1. 同步Token到Context(推荐)
如果自定义Hook从Context获取Token,需在登录时将Token同步到Context,确保全局状态与Cookie一致:
修改登录逻辑,新增Token的Context更新:
const navigate = useNavigate(); const { setData, setToken } = useUserData(); // 确保Context暴露setToken方法 const handleLogin = async (data: FormValues) => { try { const res = await normalFetch.post("/auth/login", data); const { token, user } = res.data; cookies.set("sg-auth-token", token); setData(user); setToken(token); // 将Token同步到Context toast.success("Successfully logged in."); navigate("/"); } catch (error: any) { isAxiosError(error) && toast.error(error.response?.data?.message); console.log(error); } };
对应的Context定义需包含Token状态:
// UserDataContext.tsx import { createContext, useContext, useState, ReactNode } from "react"; interface User { // 你的用户数据结构 } interface UserData { user: User | null; token: string | null; } interface UserDataContextType { data: UserData; setData: (user: User) => void; setToken: (token: string) => void; } const UserDataContext = createContext<UserDataContextType | undefined>(undefined); export const UserDataProvider = ({ children }: { children: ReactNode }) => { const [data, setDataState] = useState<UserData>({ user: null, token: cookies.get("sg-auth-token") || null // 初始化从Cookie读取 }); const setData = (user: User) => { setDataState(prev => ({ ...prev, user })); }; const setToken = (token: string) => { setDataState(prev => ({ ...prev, token })); }; return ( <UserDataContext.Provider value={{ data, setData, setToken }}> {children} </UserDataContext.Provider> ); }; export const useUserData = () => { const context = useContext(UserDataContext); if (!context) throw new Error("useUserData must be used within a UserDataProvider"); return context; };
此时自定义Hook直接从Context取Token:
const useAuthToken = () => { const { data } = useUserData(); return data.token; };
2. 让自定义Hook响应Cookie变化
如果Hook直接读取Cookie,可使用react-cookie库的useCookie Hook自动监听Cookie变化:
// 安装依赖:npm install react-cookie import { useCookie } from "react-cookie"; const useAuthToken = () => { const [token] = useCookie("sg-auth-token"); return token; };
3. 手动实现Cookie监听(无第三方库)
通过自定义事件实现Cookie变化监听:
登录时触发事件
const handleLogin = async (data: FormValues) => { try { const res = await normalFetch.post("/auth/login", data); const token = res.data.token; cookies.set("sg-auth-token", token); // 触发自定义事件通知Token更新 window.dispatchEvent(new Event("auth-token-updated")); setData(res.data.user); toast.success("Successfully logged in."); navigate("/"); } catch (error: any) { isAxiosError(error) && toast.error(error.response?.data?.message); console.log(error); } };
自定义Hook中监听事件
import { useState, useEffect } from "react"; import cookies from "你的Cookie库"; const useAuthToken = () => { const [token, setToken] = useState(cookies.get("sg-auth-token")); useEffect(() => { const handleTokenUpdate = () => { setToken(cookies.get("sg-auth-token")); }; window.addEventListener("auth-token-updated", handleTokenUpdate); return () => window.removeEventListener("auth-token-updated", handleTokenUpdate); }, []); return token; };
总结
优先选择同步Token到Context的方案,保证全局状态一致性;若需直接操作Cookie,使用react-cookie或自定义事件监听确保Hook实时获取最新Token值。
内容的提问来源于stack exchange,提问作者AlaaKudo810
相关产品推荐
相关产品推荐

