如何在 Redux 中管理嵌套的 reducer?

How to manage nested reducers in Redux?

我有两个仪表板,其中包含我想在 redux 中实现的类似数据和属性。见下文。

Dashboard 1 : {filters, widgets, custom}
Dashboard 2: {filters, widgets, custom}

我想像这样创建我的 redux 状态:

{
dashboards: {
    dashboard1:{
        filter:{ // filter related stuff},
        widgets:{ // widget related state},
        custom:{ // custom state}
    },
    dashboard2: {
        filter:{  // filter related state},
        widgets:{  // widget related state},
        custom:{ // custom state}
    }
},
auth: {// auth related stuff},
...// other state keys

}

为了实现这一点,我正在尝试对仪表板使用这样的联合减速器

// xyz.reducer.js

combineReducers({
filters: filterReducers,
widgets: widgetReducers,
custom: CustomReducers
})

现在我已经创建了一个仪表板减速器,每次用户导航到某个仪表板时都会调用它。我想根据 dashboardID 分配此状态。像 -

const dashboardReducer = (state = defaultState, action) => {
  switch (action.type) {
    case CREATE_DASHBOARD: {
      const { payload } = action;
      return {
        ...state,
        [payload.dasboardId]: // all the combined reducer state here
      };
    }

    default:
      return state;
  }
};

有人可以建议我如何实现这一目标吗?如果有人有更好的建议,我也愿意接受建议 维护这种状态结构的方法。

当然可以,只要您有办法识别与 xyz reducer 相关的所有操作并且能够识别 dashboardId.

对于您的示例,假设来自 xyz.reducer.js 的嵌套缩减程序称为 xyz:

import xyz from './xyz.reducer.js'; // or whatever

const dashboardReducer = (state = defaultState, action) => {
  switch (action.type) {
    case CREATE_DASHBOARD: {
      const { payload } = action;
      return {
        ...state,
        [payload.dashboardId]: xyz(state[payload.dashboardId], action),
      };
    }

    default:
      return state;
  }
};

假设您知道仪表板可能需要响应您的所有操作类型,并且它们都有 dashboardId 作为有效负载中的键,您可以简单地传递所有这些。

const dashboardReducer = (state = defaultState, action) => {
  switch (action.type) {
    case CREATE_DASHBOARD:
    case UPDATE_DASHBOARD_FILTER:
    case ADD_DASHBOARD_WIDGET:
    //... etc
    {
      const { payload } = action;
      return {
        ...state,
        [payload.dashboardId]: xyz(state[payload.dashboardId], action),
      };
    }

    default:
      return state;
  }
};

这有点脆弱,所以您可能想要做一些事情,比如假设应该传递任何具有仪表板 ID 的有效负载:

const dashboardReducer = (state = defaultState, action) => {
  const {payload = {}} = action;
  if (typeof payload.dashboardId !== 'undefined') {
    return {
      ...state,
      [payload.dashboardId]: xyz(state[payload.dashboardId], action),
    };
  }
  return state;
};

现在您不需要保留操作类型列表,您只需要确保所有相关操作创建者在其有效负载中包含 dashboardId