在Angular NgRx中将对象与状态合并

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

我读了这个教程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只覆盖该属性而不是整个状态。

但是当我使用调试器时,我可以看到状态get只更新了传入的属性。

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

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

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

相反,发生的事情是整个商店被JUST属性覆盖。因此,在完成上述补丁应用程序后,我们将只有authenticatedid道具集。

知道为什么我的减速机没有按预期运行吗?我读了一个article from Flavio Copes,看不到任何我错的地方。

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

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

我有一个CodeSandbox,说明我正在尝试解决的问题。

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

angular typescript ecmascript-6 ngrx
1个回答
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;
  }
};
© www.soinside.com 2019 - 2024. All rights reserved.