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

React Redux Toolkit页面刷新后出现Cannot read properties错误

问题分析与解决方案

核心原因

刷新页面后抛出Cannot read properties of undefined (reading 'length')错误,主要源于以下几点:

  • Thunk静态读取Cookie:menuSlice.js中title和token在模块初始化时获取,页面刷新时可能存在Cookie未及时读取的情况,导致API请求URL异常,最终返回的payload为undefined,state.menu被赋值为undefined。
  • Loading状态逻辑漏洞:初始status设为false,页面刷新后首次渲染会直接加载Menu组件,若API请求未完成或失败,menu可能变为undefined,组件访问length时触发错误。
  • 未处理请求失败场景:请求被拒绝时未重置menu为默认数组,若menu已被错误赋值为undefined,会导致后续渲染出错。

修复方案

1. 动态在Thunk内获取Cookie

将Cookie读取逻辑移到fetchMenu内部,确保每次调用Thunk时都能获取最新的Cookie值,同时增加空值校验:

// menuSlice.js
export const fetchMenu = createAsyncThunk("getMenuItems/title", async () => {
  const cookies = new Cookies();
  const title = cookies.get('title');
  const token = cookies.get('token');
  
  if (!title || !token) {
    return [];
  }
  
  const url = `https://xxxxxxxx/getMenuItems/${title}`;
  const data = await axios.get(url, {
    headers: { Authorization: `Bearer ${token}` },
  });
  
  return Array.isArray(data.data) ? data.data : [];
});

2. 优化Loading初始状态

将initialState中的status设为true,确保页面首次加载时直接显示Loading,避免提前渲染依赖数据的组件:

// menuSlice.js
export const menuSlice = createSlice({
  name: "menu",
  initialState: {
    menu: [],
    status: true, // 初始设为加载中
  },
  extraReducers: {
    [fetchMenu.pending]: (state) => {
      state.status = true;
    },
    [fetchMenu.fulfilled]: (state, action) => {
      state.status = false;
      state.menu = action.payload;
    },
    [fetchMenu.rejected]: (state) => {
      state.status = false;
      state.menu = []; // 请求失败时重置为数组
    },
  },
});

3. 组件内增加空值防护

在Menu组件中对siteData进行空值检查,避免直接访问length:

// Menu组件示例
function Menu({ siteData = [], siteId }) {
  // 使用可选链或默认值处理空值
  const itemCount = siteData?.length || 0;
  
  if (!siteData || siteData.length === 0) {
    return <div>暂无菜单数据</div>;
  }
  
  // 后续渲染逻辑
}

4. 完善Home页面渲染逻辑

传递数据时增加默认值,确保组件始终收到数组类型的参数:

// Home页面
return (
  <div className="row d-flex w-100 h-100 justify-content-center mx-auto px-0 ">
    <div className="row d-flex col-md-9 col-lg-9 justify-content-center col-sm-12 mx-auto px-0">
      <div className="col-md-5 col-lg-5 col-sm-12">
        <Menu siteData={menu || []} siteId={title} />
      </div>
      <div className="col-md-7 col-lg-7 col-sm-12 bg-light ">
        <Edit siteData={menu || []} siteId={title} />
      </div>
    </div>
    <div className="col-md-3 col-lg-3 col-sm-12 ">
      <input onClick={logOut} type="button" name="" id="" value="LogOut" />
    </div>
  </div>
);

内容的提问来源于stack exchange,提问作者Sarmed MQ Berwari

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 10:53:19