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

Immer报错:生产者同时返回新值并修改草稿的问题求助

解决Immer「生产者同时返回新值并修改草稿」的错误

错误原因

Immer的核心规则是:在生产者函数(你的reducer函数)中,要么直接修改传入的state草稿对象,要么返回一个全新的状态对象,二者不能同时进行。你的代码在第一个if分支里,先直接修改了state.cart[IteamIndex_dec].qnty(修改草稿),随后又返回了{...state, cart: [...state.cart]}(返回新值),这就违反了Immer的规则,导致报错。

修复方案(二选一)

方案1:只修改草稿,不返回新对象

利用Immer允许直接修改草稿的特性,直接操作state,无需返回新对象:

removeIndexCart: (state, action) => {
  const itemIndex = state.cart.findIndex(item => item.id === action.payload.id);
  if (itemIndex === -1) return; // 处理商品不存在的边界情况

  const targetItem = state.cart[itemIndex];
  if (targetItem.qnty > 1) {
    // 直接修改草稿中的商品数量
    targetItem.qnty -= 1;
  } else {
    // 直接替换草稿中的cart数组
    state.cart = state.cart.filter(el => el.id !== action.payload.id);
  }
}
  • 修正了原代码的逻辑漏洞:原if (qnty >=1)会导致qnty=1时减到0,无法触发删除逻辑,改为qnty >1时减数量,否则删除商品。
  • 增加了商品不存在的判断,避免数组越界报错。

方案2:只返回新对象,不修改草稿

完全基于不可变数据的方式,创建新的状态对象返回,不修改原草稿:

removeIndexCart: (state, action) => {
  const itemIndex = state.cart.findIndex(item => item.id === action.payload.id);
  if (itemIndex === -1) return state;

  const targetItem = state.cart[itemIndex];
  if (targetItem.qnty > 1) {
    // 创建新的cart数组,修改对应商品的数量
    const newCart = state.cart.map((item, index) => 
      index === itemIndex ? {...item, qnty: item.qnty - 1} : item
    );
    return {...state, cart: newCart};
  } else {
    // 创建过滤后的新cart数组,返回新状态
    const newCart = state.cart.filter(el => el.id !== action.payload.id);
    return {...state, cart: newCart};
  }
}
  • 全程不修改原state,通过map和filter生成新数组,符合Redux不可变更新的原则,同时满足Immer的规则。

内容的提问来源于stack exchange,提问作者Hüseyin Oral

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 12:30:40