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

为何Redux的goals状态中嵌套了来自MongoDB的同名数组?(NextJS+TS)

解决Redux Goals状态嵌套问题

你的问题核心是后端返回的响应结构包含嵌套的goals字段,但Redux Slice里直接把整个响应对象赋值给了state.goals,导致状态变成goals: { goals: [目标数组] }的嵌套结构,无法直接映射渲染。

问题分析

从你描述的状态结构来看,getGoals异步请求返回的action.payload是一个形如{ goals: [目标数据数组] }的对象,而非直接的目标数组——这和Brad Traversy原版教程的后端返回结构不一致,照搬写法自然会出问题。

解决方案

1. 修正getGoals的fulfilled处理逻辑

在goalSlice的extraReducers中,将getGoals.fulfilled的赋值语句改为取action.payload里嵌套的goals数组:

.addCase(getGoals.fulfilled, (state, action) => {
  state.isLoading = false;
  state.isSuccess = true;
  // 提取嵌套的goals数组赋值给state.goals
  state.goals = action.payload.goals;
})

2. 同步修正addGoal的处理逻辑

如果添加目标后后端返回的是{ goal: 新目标对象 }这类结构,也要对应修改addGoal.fulfilled:

.addCase(addGoal.fulfilled, (state, action) => {
  state.isLoading = false;
  state.isSuccess = true;
  // 提取返回的单个goal对象加入数组
  state.goals.push(action.payload.goal);
})

3. 优化TypeScript类型定义(可选但推荐)

替换模糊的any[],定义明确的目标类型,避免类型隐患:

// 单个目标的类型定义
type Goal = {
  _id: string;
  text: string;
  createdAt: string;
  updatedAt: string;
  // 补充后端返回的其他字段
};

type stateTypes = {
  goals: Goal[]; // 替换any[]为明确的Goal[]
  isError: boolean;
  isSuccess: boolean;
  isLoading: boolean;
  message: string; // 用小写string替代构造函数类型String
};

4. 验证后端响应结构

可以在goalService.getGoals中添加日志,确认返回结构:

// 在goalService.ts的getGoals函数内添加日志
export const getGoals = async (token: string) => {
  const response = await axios.get('/api/goals', {
    headers: { Authorization: `Bearer ${token}` }
  });
  console.log('getGoals后端响应:', response.data); // 查看实际返回结构
  return response.data;
};

修改完成后,state.goals会直接存储目标数组,即可正常使用state.goals.map(...)进行渲染。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 23:45:54