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

ReactJS路由到Profile页面时Cookie的role值被设为undefined问题

问题根因

你提供的登录逻辑中存在2个核心的时序和数据处理错误,是导致Cookie的role值被覆盖为undefined的直接原因:

  • 登录接口返回数据的处理逻辑错误:你用map遍历res.data写入Cookie,默认接口返回的是用户数组,但常规登录接口只会返回单个当前登录的用户对象。如果后端实际返回的是单个对象而非数组,调用map会遍历对象的键,导致写入Cookie时data变量为undefined,所有字段都会被写为undefined
  • 异步逻辑时序错误:Promise.allSettled本身是异步的,你既没有await它,也没有把跳转、更新login状态的逻辑放到它的回调链里,导致页面跳转、父组件状态刷新的时候,Cookie还没完成写入,甚至出现写入到一半就跳转的情况,读写不同步就会读到undefined

另外还有一个隐藏风险点:你在写完Cookie后立刻调用Cookies.get读值判断跳转,js-cookie的写入虽然是同步的,但如果是遍历写入多次的场景,也会出现读到中间状态的问题,完全可以直接用接口返回的data判断,没必要走Cookie读。

修复方案

第一步:先确认接口返回结构

在axios的then回调里加一行日志打印console.log('接口返回数据:', res.data, typeof res.data, Array.isArray(res.data)),确认返回的是数组还是单个对象:

  • 如果是单个对象,删掉map遍历逻辑,直接取字段写入Cookie即可
  • 如果确实是数组,加个判断取第一个有效用户写入,避免遍历多项覆盖Cookie

第二步:修正异步时序

把跳转、更新login状态的逻辑都放到Promise.allSettled的回调里,确保所有Cookie写入完成后再执行后续操作。

修复后核心代码示例

// 仅修改axios.then内的逻辑部分即可
axios.post(API_PATH, formData)
  .then(async (res) => { // 加async支持内部await
    if (res.data == false) {
      enqueueSnackbar('用户名或密码错误,请重试', {variant: 'error'});
      return
    }
    if (validateJSON(res.data) !== true) {
      enqueueSnackbar(res.data, {variant: 'error'});
      return
    }
    console.log('接口返回数据:', res.data)
    // 先处理数据:如果是数组取第一项,否则直接用返回对象
    const userData = Array.isArray(res.data) ? res.data[0] : res.data
    if (!userData?.user_id) {
      enqueueSnackbar('登录失败,用户数据无效', {variant: 'error'});
      destroyCookies()
      return
    }
    // 一次性写入所有Cookie 不需要多余的map遍历
    Cookies.set("user_id", userData.user_id);
    Cookies.set("profile_image", userData.profile_image);
    Cookies.set("username", userData.username);
    Cookies.set("password", userData.password);
    Cookies.set("email", userData.email);
    Cookies.set("first_name", userData.first_name);
    Cookies.set("last_name", userData.last_name);
    Cookies.set("phone_number", userData.phone_number);
    Cookies.set("dob", userData.dob);
    Cookies.set("role", userData.role);
    Cookies.set("status", userData.status);
    Cookies.set("registered_date", userData.registered_date);
    Cookies.set("gender", userData.gender);
    // 直接用返回的userData判断跳转 不需要重复读Cookie
    enqueueSnackbar("登录成功", {variant: 'success'});
    if (userData.role === "0" || userData.role === "2") {
      history.push('/dashboard');
    } else if (userData.role === "1") {
      history.push('/profile');
    } else {
      history.push('/dashboard');
    }
    setLogin(prev => prev + 1)
  })
  .catch((err) =>  {
    enqueueSnackbar(err, {variant: 'error'});
    throw Error("登录流程出错:" + err);
  });

额外排查项

如果修复后还有问题,检查Profile页面的挂载/更新逻辑:

  • 编辑个人资料接口如果没有返回role字段,不要直接把接口返回的所有字段全量写入Cookie,会把缺失的role覆盖为undefined
  • 检查有没有全局路由守卫逻辑,在跳转的时候误操作了Cookie

内容的提问来源于stack exchange,提问作者ME MYSELF

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.12 22:27:02