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

Redux reducer中workouts调用filter/map报错的修复方案

报错根因

filter is not a function、map is not a function 报错的直接原因是Redux中维护的workouts状态预期为数组类型,但实际被赋值为对象类型,所有数组原生方法无法在非数组类型上调用。
问题出在两个位置:

  • 所有接口请求的响应值没有正确解构:你使用的axios类请求工具会把后端返回的实际数据包裹在响应对象的data字段中,当前代码直接把整个响应对象作为payload传给reducer,首次执行FETCH_ALL时就把workouts状态设置成了对象,后续所有调用数组方法的操作都会触发报错。
  • reducer没有做类型校验兜底,一旦传入异常类型的payload,状态会直接变成非数组,触发连锁报错。
具体修改方案

1. 修正actions中的接口响应解构

所有调用api的位置,都需要从响应对象中解构出实际返回的业务数据,不要直接传递整个响应对象:

import { FETCH_ALL, CREATE, UPDATE, DELETE, LIKE, COMMENT_WORKOUT, COMMENT_MEAL } from '../constants/actionTypes';
import * as api from '../api';

export const getWorkouts=()=> async (dispatch)=>{
    try{
        // 从axios响应中解构出实际数据
        const { data } = await api.fetchWorkouts();
        dispatch({type:FETCH_ALL,payload:data});
        console.log(data);
    }catch(error){
        console.log(error);
    }
}

export const getWorkoutsBySearch=(searchQuery)=>async(dispatch)=>{
    try{
        const {data:{data}}=await api.fetchWorkoutsBySearch(searchQuery);
        // 后续如果要对接搜索列表渲染,记得在这里dispatch对应action,传入数组类型的data
        console.log(data);
    }catch(error){
        console.log(error);
    }
}

export const createWorkout=(workout)=>async(dispatch)=>{
    try{
        // 解构新建完成返回的单条workout数据
        const { data } = await api.createWorkout(workout);
        dispatch({type:CREATE,payload:data});
        console.log(data);
    }catch(error){
        console.log(error.message);
    }
}

export const updateWorkout=(id,workout)=>async(dispatch)=>{
    try{
        // 解构更新完成返回的单条workout数据
        const { data } = await api.updateWorkout(id,workout);
        dispatch({type:UPDATE,payload:data})
    }catch(error){
        console.log(error);
    }
}

export const deleteWorkout = (id) => async (dispatch) => {
    try {
      await api.deleteWorkout(id);
      dispatch({ type: DELETE, payload: id });
    } catch (error) {
      console.log(error);
    }
};

export const likeWorkout=(id)=>async(dispatch)=>{
    try{
        // 解构点赞完成返回的单条workout数据
        const { data } = await api.likeWorkout(id);
        console.log(data)
        dispatch({type:LIKE,payload:data})
    }catch(error){
        console.log(error);
    }
}

export const postCommentOnWorkout=(data)=>async(dispatch)=>{
    try{
        // 解构评论提交完成返回的单条workout数据
        const { data: updatedWorkout } = await api.postCommentOnWorkout(data);
        dispatch({type:COMMENT_WORKOUT,payload:updatedWorkout})
    }catch(error){
        console.log(error);
    }
}

export const postCommentOnMeal=(data)=>async(dispatch)=>{
    try{
        // 解构餐食评论提交完成返回的数据
        const { data: updatedMeal } = await api.postCommentOnMeal(data);
        dispatch({type:COMMENT_MEAL,payload:updatedMeal})
    }catch(error){
        console.log(error);
    }
}

2. 给reducer增加类型兜底

在reducer中增加数组类型校验,避免异常payload导致状态类型错误:

import { FETCH_ALL, CREATE, UPDATE, DELETE, LIKE, COMMENT_WORKOUT } from '../constants/actionTypes';

export default (workouts=[],action)=>{
   switch(action.type){
    case FETCH_ALL:
        // 确保存入状态的是数组,异常情况兜底为空数组
        return Array.isArray(action.payload) ? action.payload : [];
    case CREATE:
        return [...workouts, action.payload];
    case UPDATE:
        return Array.isArray(workouts) 
            ? workouts.map((workout) => workout._id === action.payload._id ? action.payload : workout)
            : [];
    case LIKE:
        return Array.isArray(workouts) 
            ? workouts.map((workout) => workout._id === action.payload._id ? action.payload : workout)
            : [];
    case DELETE:
        return Array.isArray(workouts)
            ? workouts.filter((workout) => workout._id !== action.payload)
            : [];
    case COMMENT_WORKOUT:
        return Array.isArray(workouts)
            ? workouts.map((workout) => workout._id === action.payload._id ? action.payload : workout)
            : [];
    default:
        return workouts;
   }
}
验证方式

修改完成后,在FETCH_ALL对应的dispatch位置打日志,确认传入的payload是workout对象组成的数组,后续增删改查、点赞、评论操作就可以正常调用map、filter方法,不会再触发类型报错。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 17:21:34