首页 > 解决方案 > Ngrx 存储:更新 ActionReducerMap 之外的公共状态

问题描述

我有一个初始状态类似于的 ngrx 商店:

const state = { 
    child1: {...},
    child2: {...},
}

使用 ActionReducerMap 如下:

const reducerMap = {
    child1: reducer1,
    child2: reducer2,
}

现在我想在与 child1 和 child2 相同的级别添加一个“加载”状态,以跟踪两个孩子(它们是相互连接的)的加载。为此,我将初始状态更新如下:

const state = { 
    child1: {...},
    child2: {...},
    loading: false,
}

我尝试使用位于 reducer1 和 reducer2 顶部的 metareducer,如下所示:

export function metaReducer(reducer) {
    return function reduce(state, action) {
        switch(action.type) {
            case CommonActionTypes.UpdateLoading: {
                return {
                    ...,
                    loading: action.loading
                }
            }
            default:
                return reducer(state, action);
        }
    }
}

我将其添加到功能存储中,如下所示:

StoreModule.forFeature('myStore', compose(metaReducer, combineReducers)(reducerMap))

在应用程序中,我在更新 child1 和 child2 的某些效果期间调用 UpdateLoading 操作。但是,这并没有像我预期的那样工作。

  1. 首先,初始状态根本不尊重“加载”变量——它仍然认为原始状态是
{ 
    child1: {...},
    child2: {...},
}
  1. 状态中的“正在加载”变量仅在调用 UpdateLoading 操作时更新。通过所有后续操作,它将从状态中删除。这很奇怪,因为唯一作用于它的减速器是元减速器,而减速器 1 和减速器 2 分别作用于子状态 child1 和 child2。

使用 meta-reducer 更新公共状态是否正确?我怎样才能使这项工作?

标签: angularngrxngrx-storengrx-effects

解决方案


在这两种情况下都尝试使用 reducer 函数:

export function metaReducer(reducer) {
    return function reduce(state, action) {
        switch(action.type) {
            case CommonActionTypes.UpdateLoading: {
                return reducer({ // <- wrap it.
                    ...state,
                    loading: action.loading
                }, action);
            }
            default:
                return reducer(state, action);
        }
    }
}

就像这样.forRoot

StoreModule.forRoot({/*...*/}, {
  metaReducers: [metaReducer],
}),

推荐阅读