Angular NgRx中状态合并对象的麻烦

时间:2019-04-21 02:41:56

标签: angular typescript ecmascript-6 ngrx

我阅读了本教程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覆盖/合并/修补现有对象。

相反,将发生的情况是整个商店都被该属性覆盖。因此,在使用了提到的补丁应用程序之后,我们将只设置authenticatedid道具。

有什么主意为什么我的减速器表现不如预期?我读了article from Flavio Copes,却看不到我哪里出了问题。

我还尝试使用Object.assign()合并对象。

return Object.assign({}, state, { app: action.payload });

我有一个CodeSandbox,可以说明我要解决的问题。

https://codesandbox.io/s/oxj7xx5n35?fontsize=14

1 个答案:

答案 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;
  }
};