【问题标题】:Accessing a reducer state from within another reducer in NGRX从 NGRX 中的另一个减速器中访问减速器状态
【发布时间】:2019-04-20 20:34:02
【问题描述】:

如何在 NGRX 的另一个减速器中访问(读取)减速器状态? 这是一个与this 非常相似的问题。 NGRX 是否为此提供任何其他解决方案?

【问题讨论】:

  • 你能说得更具体些吗?一般来说,你不应该这样做! Reducer 必须是一个纯函数。你能解释一下你想要达到的目标吗?
  • 我不想改变另一个减速器的状态,只是为了阅读它。我的减速器逻辑需要了解驻留在不同减速器中的某些状态
  • 纯函数只能使用其参数,即“状态”和“动作”。保持“Redux”模式你可以做的是通过在 Effect (withLatestFrom(store.pipe(select(selector)))) 中选择它来添加你需要的状态图片,然后使用 reducer 中的值
  • 抱歉,您所说的“reducer”是指状态,对吧?

标签: ngrx


【解决方案1】:

我在考虑做类似的事情时偶然发现了这个问题。我需要来自不同 reducer 的一些状态信息的副本,作为临时“编辑”数据集,可以取消并恢复为“已记录”数据集。

我最终扩展了我的 UI 缩减器(保存当前用户会话的状态/编辑的缩减器)以包含一个属性来保存来自我的数据缩减器的数据副本(表示存储在数据库中的数据的缩减器)。该数据通过“开始”操作传入。

这是我的 UI 操作的缩写副本:

import { Action } from "@ngrx/store";
import {
  ICableFeature
} from "../../shared/models";

export enum UIActionTypes {
  ...
  UI_EDIT_CUSTOM_TAGS_START = "[UI] Edit Custom Tags Start",
  UI_EDIT_CUSTOM_TAGS_UPDATE = "[UI] Edit Custom Tags Update",
  UI_EDIT_CUSTOM_TAGS_SAVE = "[UI] Edit Custom Tags Save",
  UI_EDIT_CUSTOM_TAGS_SUCCESSFUL = "[UI] Edit Custom Tags Successful",
  UI_EDIT_CUSTOM_TAGS_FAILED = "[UI] Edit Custom Tags Failed",
  UI_EDIT_CUSTOM_TAGS_CANCELED = "[UI] Edit Custom Tags Canceled"
}

...

export class EditCustomTagsStart implements Action {
  readonly type = UIActionTypes.UI_EDIT_CUSTOM_TAGS_START;

  constructor(public payload: ICableFeature) {}
}

export class EditCustomTagsUpdate implements Action {
  readonly type = UIActionTypes.UI_EDIT_CUSTOM_TAGS_UPDATE;

  constructor(public payload: ICableFeature) {}  // This payload has a copy of the data I needed from the other reducer.  Make sure it is a copy and not the same object!
}

export class EditCustomTagsSave implements Action {
  readonly type = UIActionTypes.UI_EDIT_CUSTOM_TAGS_SAVE;

  constructor() {}
}

export class EditCustomTagsSuccessful implements Action {
  readonly type = UIActionTypes.UI_EDIT_CUSTOM_TAGS_SUCCESSFUL;

  constructor() {}
}

export class EditCustomTagsFailed implements Action {
  readonly type = UIActionTypes.UI_EDIT_CUSTOM_TAGS_FAILED;

  constructor(public payload: string) {}
}

export class EditCustomTagsCanceled implements Action {
  readonly type = UIActionTypes.UI_EDIT_CUSTOM_TAGS_CANCELED;

  constructor() {}
}

export type UIActions =
  ...
  | EditCustomTagsStart
  | EditCustomTagsUpdate
  | EditCustomTagsSuccessful
  | EditCustomTagsFailed
  | EditCustomTagsCanceled;

这是我的 UI reducer 的缩写副本:

import * as fromUI from "../actions/ui.actions";
import {
  IOrchestratorState,
  IOrchestratorStatusState,
  ICableFeature
} from "../../shared/models";
export const uiFeatureKey = "ui";

export interface State {
  showScroll: boolean;
  fillingGaps: boolean;
  fillGapStatus: IOrchestratorStatusState;
  currentFillGapState: IOrchestratorState;
  editingCustomTags: boolean;
  customTagEdits: ICableFeature;
}

export const initialState: State = {
  showScroll: true,
  fillingGaps: false,
  fillGapStatus: null,
  currentFillGapState: null,
  editingCustomTags: false,
  customTagEdits: null
};

export function reducer(state = initialState, action: fromUI.UIActions) {
  switch (action.type) {
    ...
    case fromUI.UIActionTypes.UI_EDIT_CUSTOM_TAGS_START:
      return {
        ...state,
        editingCustomTags: true,
        customTagEdits: action.payload  // This is a copy of the data I needed from the other reducer
      };
    case fromUI.UIActionTypes.UI_EDIT_CUSTOM_TAGS_UPDATE:
      return {
        ...state,
        customTagEdits: action.payload  // This is the updated information from user edits, not saved.  
                                        // I can also create a router guard that checks to makes sure the data in this 
                                        // property and the data in my Data store are the same before the page is deactivated
      };
    case fromUI.UIActionTypes.UI_EDIT_CUSTOM_TAGS_SUCCESSFUL:
    case fromUI.UIActionTypes.UI_EDIT_CUSTOM_TAGS_FAILED:
    case fromUI.UIActionTypes.UI_EDIT_CUSTOM_TAGS_CANCELED:
      return {
        ...state,
        editingCustomTags: false,
        customTagEdits: null
      };

    default:
      return state;
  }
}

如您所见,通过将数据从一个 reducer 传递到另一个 reducer 作为操作中的有效负载,我能够在我的 reducer 中维护纯函数。

我希望这会有所帮助!

【讨论】:

    猜你喜欢
    • 2017-07-03
    • 1970-01-01
    • 1970-01-01
    • 2017-08-21
    • 1970-01-01
    • 2019-02-14
    • 2021-10-13
    • 1970-01-01
    • 2019-06-11
    相关资源
    最近更新 更多