首页 > 解决方案 > 在Angular NgRx中将对象与状态合并的问题

问题描述

我阅读了有关创建 NgRx 存储的教程,因此我创建了一个具有以下形状的简单存储。

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现有状态的属性,我希望减速器只覆盖该属性而不是整个状态。

但是当我使用调试器单步执行时,我可以看到状态获取已更新,仅包含传入的属性。

所以如果我有这样的初始状态:

export const initialAppState: IAppState = {
  app: {
    id: null,
    testMode: false,
    authenticated: false,
    user: null,
    role: 'END_USER'
  }
};

然后我做PatchApp{authenticated: true, id: 'someid'}我希望action.payload覆盖/合并/修补现有对象。

取而代之的是,整个商店都被该属性覆盖了。因此,在完成上述补丁应用程序后,我们将只设置authenticatedandid道具。

知道为什么我的减速器没有按预期运行吗?我读了一篇来自 Flavio Copes的文章,没有发现任何我出错的地方。

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

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

我有一个 CodeSandbox 来说明我要解决的问题。

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

标签: angulartypescriptecmascript-6ngrx

解决方案


不确定我是否正确地尝试了您正在尝试做的事情,但似乎您只想修补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;
  }
};

推荐阅读