为何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
相关产品推荐
相关产品推荐

