我正在使用 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”
Redux 模式的基本原则是状态及其部分的不变性,因为它让我们仅通过对象引用来检测更改,而不是比较整个对象。
在您的减速器中,您不能直接分配状态属性(
state.actualTrips =
),因为更改检测器(和选择器)不会检测到它已更改。
要修改状态,您需要返回包含新修改的状态副本。
const time = action.payload;
return {
...state,
actualTrips: [...(state.schedulings[time] || [])]
}
如果你想改变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,
},
}),
当我更改模板中的输入值时,发生了该错误。我正在使用 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));
对我来说,我的 app.module 中需要以下语法
StoreModule.forRoot(reducers, {
runtimeChecks: {
strictStateImmutability: false,
strictActionImmutability: false,
},
}),
感谢上面 Dharman 的帖子...
我在https://stackoverflow.com/a/58279719
找到了答案只需将状态复制到新对象中
const oldState = getState();
let state = JSON.parse(JSON.stringify(oldState)); // here
state.propertyToChange = "newValue";
patchState({
...state
});
如果您有一组对象,您可能还想安装 lodash 库,它允许您进行深度克隆。
npm i --save lodash
npm install --save-dev @types/lodash
然后在你的组件中:
import * as _ from 'lodash';
并使用它:
cloneObject = _.cloneDeep('your object')