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

问题描述 投票:0回答:6

我正在使用 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”

javascript angular typescript javascript-objects ngrx
6个回答
23
投票

Redux 模式的基本原则是状态及其部分的不变性,因为它让我们仅通过对象引用来检测更改,而不是比较整个对象。

在您的减速器中,您不能直接分配状态属性(

state.actualTrips =
),因为更改检测器(和选择器)不会检测到它已更改。

要修改状态,您需要返回包含新修改的状态副本。

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

12
投票

如果你想改变state.actualTrips = myNewValue是不允许的,因为有一个严格的设置。所以一种方法是可以clonedeep并返回对象,比如newState =cloneOfState...我没有测试它。所以我更改了 Store 的 app.module 中的设置。 我的示例:将 strictStateImmutability 更改为 false(此处为完整文档: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,
        },
    }),

6
投票

当我更改模板中的输入值时,发生了该错误。我正在使用 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));

1
投票

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

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

感谢上面 Dharman 的帖子...


0
投票

我在https://stackoverflow.com/a/58279719

找到了答案

只需将状态复制到新对象中

const oldState = getState();

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

state.propertyToChange = "newValue";

patchState({
   ...state
});

0
投票

如果您有一组对象,您可能还想安装 lodash 库,它允许您进行深度克隆。

npm i --save lodash
npm install --save-dev @types/lodash

然后在你的组件中:

import * as _ from 'lodash';

并使用它:

cloneObject = _.cloneDeep('your object')
© www.soinside.com 2019 - 2024. All rights reserved.