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

为什么Redux reducer中调用自定义state类方法会得到意外结果?

问题原因分析

你的问题核心是CartState类中使用箭头函数定义的实例方法,this被永久绑定到了首次创建的实例上,和不可变更新的逻辑冲突。

  • 你使用类属性箭头函数语法(haveItem = () => {}、selectPackage = () => {})定义的方法,不属于类原型,是每个实例独有的属性。这类方法的this会在实例初始化时就绑定死到当前实例,永远不会改变。
  • Redux要求不可变更新,你调用iObject.updateKeyImmutably返回的是一个新的状态对象,这个新对象复制了旧实例上的所有属性,包括绑定了旧实例this的箭头函数方法。
  • 当你调用新状态对象的selectPackage方法时,方法内部的this仍然指向最开始的初始状态实例,自然拿不到上一次更新后新状态里的item值,只会读取到过时的旧数据。
  • 第二种写法没有使用类的方法,直接读取当前传入reducer的state的属性,不受this绑定问题影响,所以结果符合预期。

解决方案

  1. 最简单的修复是把类的实例方法改成普通原型方法,取消箭头函数绑定:
export class CartState {
  item: CartItem

  // 去掉箭头函数,用普通方法定义,this会动态绑定到调用方
  haveItem(tourId: string) {
    const newItem = this.item ? iObject.shallowCloneTypeSafe(this.item) : new CartItem()
    newItem.tourId = tourId
    return iObject.updateKeyImmutably(this, 'item', newItem)
  }

  selectPackage(packageId: string) {
    const newItem = iObject.updateKeyImmutably(this.item, 'packageId', packageId)
    return iObject.updateKeyImmutably(this, 'item', newItem)
  }
  static getInitialState = () => new CartState()
}
  1. 更符合Redux设计规范的方案是直接使用普通对象作为状态,不用class实例,避免this绑定、序列化等额外问题,也就是你第二种写法的逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 06:15:04