typescript Ngrx:无法分配给对象“[Object]”的只读属性“Property”

mwg9r5ms  于 2023-06-24  发布在  TypeScript
关注(0)|答案(5)|浏览(219)

我正在使用ngrx商店。
在我的状态我必须物品

export interface ISchedulesState {
  schedulings: ISchedules;
  actualTrips: ISchedule[];
}

下面是我的接口

export interface ISchedules {
  [key: string]: ISchedule[];
}

export interface ISchedule {
  dest: number;
  data: string
}

在减速器中我更新actualTrips

export const SchedulingReducers = (
  state = initialSchedulingState,
  action: SchedulesAction
): ISchedulesState => {
  switch (action.type) {
    case ESchedulesActions.GetSchedulesByDate: {
      return {
        ...state
      };
    }
    case ESchedulesActions.GetSchedulesByDateSuccess: {
      return {
        ...state,
        schedulings: action.payload
      };
    }
    case ESchedulesActions.GetSchedulesByTime: {
      let time = action.payload;
      state.actualTrips = [...(state.schedulings[time] || [])]; // if not data return empty array
      return state;
    }
    default:
      return state;
  }
};

但实际上我得到一个错误
错误类型错误:无法分配给对象“[object Object]”的只读属性“actualTrips”

t1qtbnec

t1qtbnec1#

Redux模式的基本原理是状态及其部分的不变性,因为它让我们只通过对象引用来检测变化,而不是比较整个对象。
在reducer中,您不能直接分配状态属性(state.actualTrips =),因为更改检测器(和选择器)不会检测到它已更改。
若要修改状态,请返回状态的一个副本,其中包含新的修改。

const time = action.payload;
  return {
      ...state,
      actualTrips: [...(state.schedulings[time] || [])]
  }
rqmkfv5c

rqmkfv5c2#

如果要更改状态,则不允许使用actualTrips = myNewValue,因为存在严格的Setting。因此,一种方法是可以clonedeep并返回对象,如newState = cloneOfState...我没测试过。所以我在应用程序模块中更改了Store的设置。我的例子:将strictStateImmutability更改为false(此处完整Docu:https://ngrx.io/guide/store/configuration/runtime-checks

StoreModule.forRoot(ROOT_REDUCERS_TOKEN, {
        metaReducers,
        runtimeChecks: {
            // strictStateImmutability and strictActionImmutability are enabled by default
            strictStateSerializability: true,
            strictActionSerializability: true,
            strictActionWithinNgZone: true,
            strictActionTypeUniqueness: true,
            // if you want to change complexe objects and that we have. We need to disable these settings
            // change strictStateImmutability, strictActionImmutability
            strictStateImmutability: false, // set this to false
            strictActionImmutability: true,
        },
    }),
rqmkfv5c

rqmkfv5c3#

当我更改模板中的输入值时,我就发生了这个错误。我使用的是Angular11 + NGRX11,所以我知道我被 store 更改了一个值,这是我的修复:

之前:

this.store.dispatch(new Actions.LoginUser({ user: this.user }));

之后:

const clone = { 
  user: Object.assign({}, this.user) 
 };
 this.store.dispatch(new Actions.LoginUser(clone));
0vvn1miw

0vvn1miw4#

我在https://stackoverflow.com/a/58279719找到了答案
只需将状态复制到新对象中

const oldState = getState();

let state = JSON.parse(JSON.stringify(oldState)); // here 

state.propertyToChange = "newValue";

patchState({
   ...state
});
3pmvbmvn

3pmvbmvn5#

对我来说,我需要在我的app.module中使用以下语法

StoreModule.forRoot(reducers, {
          runtimeChecks: {
            strictStateImmutability: false,
            strictActionImmutability: false,
          },
        }),

这是Dharman在上面的帖子...

相关问题