You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React登录页面TypeError报错排查及过期登出逻辑优化求助

React登录状态管理问题修复方案

核心问题分析

  1. 请求失败报错:网络请求异常时(如断网、超时),err.response可能为undefined,直接访问err.response.data会触发TypeError。
  2. 日期判断逻辑失效:登录成功后立即读取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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 13:11:16