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

Angular 18中使用NGRX实现购物车时,添加第二个商品出现Cannot read properties of undefined (reading 'product')错误

Angular 18中使用NGRX实现购物车时,添加第二个商品出现Cannot read properties of undefined (reading 'product')错误

我仔细看了你的代码,很快就定位到了问题的根源:你在分发addToCart action时,参数格式完全不符合要求,而且没有把Gadget正确包装成CartItem类型,再加上reducer里用了太多any类型,导致TypeScript没能提前帮你发现问题,最终在第二次添加商品时触发了运行时错误。

错误的具体原因

  1. 你的addToCart action要求的参数是{ gadget: CartItem },但在AddGadgetComponent里,你直接把Gadget对象传了进去:
    this.store.dispatch(addToCart(this.gadget)); // 这里传的是Gadget,不是CartItem,也不符合action的参数结构
    
  2. 这导致第一次添加的商品,其实是直接把Gadget对象塞进了购物车(而不是CartItem)。当你第二次添加商品时,reducer遍历购物车列表,尝试访问i.product.id,但此时列表里的第一个条目是Gadget(它没有product属性),所以i.product是undefined,自然就抛出了Cannot read properties of undefined (reading 'product')的错误。

一步步解决问题

1. 修正AddGadgetComponent中的action分发逻辑

你需要把Gadget包装成CartItem类型,并且严格按照action要求的参数结构传递:

import { CartItem } from '../shared/models/cart.item';
import { Gadget } from './gadget.model';
// ...

export class AddGadgetComponent implements OnInit {
  @Input() gadget: Gadget; // 这里指定正确类型,不要用any
  constructor(private store: Store) { }

  addGadget() {
    console.log("Adding gadget to cart", this.gadget.id);
    // 1. 把Gadget包装成CartItem,默认quantity为1
    const cartItem: CartItem = {
      product: this.gadget,
      quantity: 1
    };
    // 2. 按action要求的结构传递参数
    this.store.dispatch(addToCart({ gadget: cartItem }));
  }
}

2. 给reducer添加严格的类型定义,去掉any

用具体类型替代any,让TypeScript在开发阶段就帮你检查错误:

import { createReducer, on } from '@ngrx/store';
import { addToCart } from './cart.action';
import { CartState } from './cart.state';
import { CartItem } from '../shared/models/cart.item';

export const initialState: CartState = {
  cart: []
};

export const cartReducer = createReducer(
  initialState,
  on(addToCart, (state: CartState, { gadget }) => {
    // 现在所有类型都是明确的,不会出现隐性错误
    const existingGadget = state.cart.find(item => item.product.id === gadget.product.id);
    
    if (existingGadget) {
      return {
        ...state,
        cart: state.cart.map(item => 
          item.product.id === gadget.product.id 
            ? { ...item, quantity: item.quantity + gadget.quantity } 
            : item
        )
      };
    } else {
      return {
        ...state,
        cart: [...state.cart, gadget]
      };
    }
  })
);

3. 可选:给AddGadgetComponent的输入属性指定正确类型

把@Input() gadget: any;改成@Input() gadget: Gadget;,这样TypeScript会帮你确保输入的是正确的Gadget对象。

验证修改后的流程

  • 点击「Add To Cart」时,会正确创建CartItem并分发给action
  • reducer处理的都是符合CartItem类型的条目,不会再出现i.product为undefined的情况
  • 重复添加同一个商品时,会正确增加数量;添加新商品时,会在购物车中新增条目

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.09 03:03:16