我阅读了本教程on creating a NgRx store,所以我创建了一个具有以下形状的简单商店。
export const initialState: IState = {
app: initialAppState
};
export function getInitialState(): IState {
return initialState;
}
export interface IApp {
id?: string;
testMode?: boolean;
authenticated?: boolean;
user?: User;
role?: string;
}
export interface IAppState {
app: IApp;
}
export const initialAppState: IAppState = {
app: {
id: null,
testMode: false,
authenticated: false,
user: null,
role: 'END_USER'
}
};
它具有一个看起来像这样的减速器,动作为PatchApp
export const appReducers = (state = initialAppState, action: AppActions): IAppState => {
switch (action.type) {
case AppActionTypes.PatchApp: {
return { ...state, app: action.payload };
}
default:
return state;
}
};
现在对我来说,这似乎非常简单。我们有一个初始状态,存储在app
属性中。如果我们得到一个有效载荷来更新现有状态的authenticated
属性,那么我期望reducer会覆盖该属性而不是整个状态。
但是,当我逐步使用调试器时,我可以看到仅使用传入的属性来更新状态。
所以,如果我的初始状态是这样的:
export const initialAppState: IAppState = {
app: {
id: null,
testMode: false,
authenticated: false,
user: null,
role: 'END_USER'
}
};
然后我对PatchApp
做{authenticated: true, id: 'someid'}
,我希望action.payload
覆盖/合并/修补现有对象。
相反,将发生的情况是整个商店都被该属性覆盖。因此,在使用了提到的补丁应用程序之后,我们将只设置authenticated
和id
道具。
有什么主意为什么我的减速器表现不如预期?我读了article from Flavio Copes,却看不到我哪里出了问题。
我还尝试使用Object.assign()
合并对象。
return Object.assign({}, state, { app: action.payload });
我有一个CodeSandbox,可以说明我要解决的问题。
答案 0 :(得分:2)
不确定我是否知道您要执行的操作,但是似乎您只想修补状态的app
部分。如果是这样,您应该这样做:
export const appReducers = (state = initialAppState, action: AppActions): IAppState => {
switch (action.type) {
case AppActionTypes.PatchApp: {
return {
...state,
app: {...state.app, ...action.payload}
};
}
default:
return state;
}
};