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

React+Redux应用中Reducer添加元素后State异常变为4且出现todos.map is not a function错误的问题排查

解决Redux Reducer添加元素后State变为数值且map报错的问题

我一眼就看出问题出在你使用Array.push()的方式上,这既违反了Redux的不可变更新原则,又因为push()本身的特性把你的state变成了数字,直接导致了todos.map is not a function错误。

问题根源拆解

  1. push()返回的是数组长度,不是新数组
    你写的newTodos = newTodos.push(action.payload),这里push()方法执行后会返回数组的新长度,而不是修改后的数组本身。所以触发ADD_TODO后,你的state就从数组变成了一个数值(比如你看到的4,应该是之前几次操作后累计的数组长度)。

  2. 直接修改了原state
    newTodos = state是引用赋值,这时候newTodos和state指向同一个数组,修改newTodos就等于修改了原state,这完全违反了Redux要求的state不可变原则——Reducer必须是纯函数,不能直接修改传入的state。

修复后的Reducer代码

要正确添加元素,你需要创建一个新数组,而不是修改原数组。推荐用这两种方式:

方式1:使用扩展运算符(最常用)

export const reducer = (state = todos, action) => { 
  switch (action.type) { 
    case ADD_TODO: 
      // 创建原数组的浅拷贝,再添加新元素
      return [...state, action.payload];
    case DELETE_TODO: 
      // 后续逻辑这里补充
      return state;
    case UPDATE_TODO: 
      // 后续逻辑这里补充
      return state;
    default: 
      return state; 
  } 
};

方式2:使用concat()方法

case ADD_TODO: 
  // concat返回新数组,不会修改原数组
  return state.concat(action.payload);

为什么这样有效?

  • 扩展运算符[...state]会复制原数组的所有元素,生成一个全新的数组,再把action.payload添加到末尾,返回这个新数组作为新的state。
  • concat()方法同样会返回一个包含原数组元素和新元素的新数组,不会对原state造成任何修改。

这样你的state始终保持数组类型,组件里的todos.map()就能正常执行了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 04:17:29