React登录页面TypeError报错排查及过期登出逻辑优化求助
React登录状态管理问题修复方案
核心问题分析
- 请求失败报错:网络请求异常时(如断网、超时),
err.response可能为undefined,直接访问err.response.data会触发TypeError。 - 日期判断逻辑失效:登录成功后立即读取Context中的
user.activeUntil,但React状态更新是异步的,此时user仍为旧值(null),导致无法正确获取过期时间。
修复方案
1. 安全处理请求错误
在handleClick的catch块中,先校验err.response是否存在,再获取错误数据,同时提供兜底错误信息:
catch (err) { let errorData = { message: '登录失败,请检查网络或账号信息' }; // 优先取接口返回的错误数据 if (err.response?.data) { errorData = err.response.data; } // 网络类错误取错误消息 else if (err.message) { errorData.message = err.message; } dispatch({ type: "LOGIN_FAILURE", payload: errorData }); }
2. 优化登录后日期判断逻辑
登录成功后直接从接口返回数据中获取activeUntil,避免依赖异步更新的Context状态;同时将日期字符串转为Date对象进行比较,确保判断准确:
const handleClick = async (e) => { e.preventDefault(); dispatch({ type: "LOGIN_START" }); const currentDate = new Date(); try { const res = await axios.post("/auth/signin", credentials); const userData = res.data.details; dispatch({ type: "LOGIN_SUCCESS", payload: userData }); // 直接从接口返回值中读取过期时间并转为Date对象 const activeUntilDate = new Date(userData.activeUntil); // 过期时间早于当前时间则执行登出 if (activeUntilDate <= currentDate) { dispatch({ type: "LOGOUT" }); console.log("您的合同已过期,请联系管理员"); } else { navigate("/myinfo"); } } catch (err) { let errorData = { message: '登录失败,请检查网络或账号信息' }; if (err.response?.data) { errorData = err.response.data; } else if (err.message) { errorData.message = err.message; } dispatch({ type: "LOGIN_FAILURE", payload: errorData }); } };
3. 实现页面加载时自动登出
在AuthContextProvider中添加监听逻辑,当用户状态变化或页面加载时,自动检查账号是否过期并执行登出:
export const AuthContextProvider = ({ children }) => { const [state, dispatch] = useReducer(AuthReducer, INITIAL_STATE); useEffect(() => { localStorage.setItem("user", JSON.stringify(state.user)); }, [state.user]); // 监听用户状态,自动检查过期 useEffect(() => { if (state.user?.activeUntil) { const currentDate = new Date(); const activeUntilDate = new Date(state.user.activeUntil); if (activeUntilDate <= currentDate) { dispatch({ type: "LOGOUT" }); console.log("您的合同已过期,已自动登出"); } } }, [state.user, dispatch]); return ( <AuthContext.Provider value={{ user: state.user, loading: state.loading, error: state.error, dispatch, }} > {children} </AuthContext.Provider> ); };
内容的提问来源于stack exchange,提问作者Mega Animenia
相关产品推荐
相关产品推荐

