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

React TodoList点击Edit报错:Cannot read properties of undefined (reading 'map')

React TodoList 点击Edit后状态变为undefined的问题分析与修复

问题描述

实现React简易TodoList时,点击Edit按钮触发报错:Cannot read properties of undefined (reading 'map'),调试发现退出reducer作用域后tasks状态变为undefined。

问题根源

在reducer的edit分支中,错误使用了Array.forEach()方法:

case "edit": {
  const tempObj = state.forEach((item) => {
    if (item.id === action.id) {
      return { ...item, isEditMode: !item.isEditMode };
    } else return item;
  });
  return tempObj;
}

forEach()方法的返回值始终是undefined,当reducer返回这个值时,tasks状态会被直接替换为undefined,后续执行tasks.map()自然触发报错。

修复方案

将forEach()替换为Array.map(),map()会返回全新数组,符合reducer纯函数的要求(返回新状态,不修改原状态):

case "edit": {
  return state.map((item) => {
    if (item.id === action.id) {
      return { ...item, isEditMode: !item.isEditMode };
    }
    return item;
  });
}

额外优化建议

  1. 禁止直接修改状态对象
    当前代码中直接修改item.task = e.currentTarget.value违反React状态不可变原则,应新增update类型的action,通过dispatch更新任务内容:
// reducer新增分支
case "update": {
  return state.map(item => {
    if (item.id === action.id) {
      return { ...item, task: action.task };
    }
    return item;
  });
}

// 输入框onChange修改为
onChange={(e) => {
  dispatch({ type: "update", id: item.id, task: e.currentTarget.value });
}}
  1. 优化ID生成逻辑
    使用useRef生成递增ID,避免随机ID重复风险:
const idRef = useRef(0);
const idCreator = () => {
  return idRef.current++;
};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 13:21:01