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

NgRx Reducer中修改对象属性报对象不可扩展错误

问题根因

NgRx 全局 Store 默认开启严格不可变校验,所有存入 Store 的对象都会被冻结(内部通过Object.freeze实现),禁止直接修改原对象属性、禁止给原对象新增/删除属性。你在 reducer 中直接给传入的pokemon对象赋值isAdded属性,本质是直接修改 Store 中已冻结的原状态对象,因此抛出Cannot add property isAdded, object is not extensible错误。

你之前的操作存在两个明显问题:

  • 直接修改 Store 中冻结的原对象:违反 NgRx 不可变更新原则,是报错的核心原因
  • 误用Object.preventExtensions():该API的作用是主动将对象设置为不可扩展状态,禁止后续给对象新增属性,不管放在赋值操作前还是后,都和修复目标完全相悖,无法解决报错
修复方案

严格遵循 NgRx 的不可变数据原则,所有状态修改都不能直接操作原对象引用,必须基于原对象创建新副本,在副本上修改属性后再返回新状态。

修正后的 Reducer 代码如下:

on(addToCart, (state, { pokemon }) => {
  // 基于原pokemon创建浅拷贝,在副本上修改属性
  const updatedPokemon: PokemonModel = {
    ...pokemon,
    isAdded: true
  };

  return {
    ...state,
    loading: false,
    error: false,
    pokemons: [
      ...state.pokemons.filter((pk) => pk.name !== pokemon.name),
      updatedPokemon
    ],
  };
}),
额外注意事项

你从 PokeApi 获取的原始宝可梦数据默认不包含isAdded、quantity这两个自定义字段,需要在第一次把API返回数据存入 Store 时,就补全这两个字段的初始值(比如isAdded: false、quantity: 1),避免后续操作出现字段缺失问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 13:31:12