首页 > 解决方案 > 使用 combineReducers 时设置 reducer 及其子 reducer 的状态

问题描述

我正在扩展仅限本地的 React 应用程序的功能以连接到 API。这是我重构之前的代码。您会看到我正在从全局窗口变量 INIT_STATE 设置初始状态,该变量还包括一些其他根级对象。

我专注于这些根级对象之一,称为“项目”。

对于项目减速器,我正在规范化(使用 normalizr)这样的状态并组合减速器以获得规范化实体的使用减速器:

window.PROJECTS_STATE = fromJS(normalize(window.INIT_STATE.projects, projectsSchema));

const result = (state = window.PROJECT_STATE.get('result'), action) => {
  switch (action.type) {
    default:
      return state;
  }
};

// In these reducers, currently, I'm getting init_state from window.PROJECTS_STATE
// i.e. window.PROJECT_STATE.entities.projects), which has been normalized above
const entities = combineReducers({
  projects,
  items,
  events,
});


// Here is where I'd like to handle an action to normalize and 
// overwrite the state of `projects` and all it's sub-reducers
export default () => combineReducers({
  entities,
  result,
});

在我的重构中,我已经分派了操作以在我的顶级容器中获取和接收 API 请求。GET_REQUEST_SUCCESS我可以通过处理这些减速器中的操作以返回响应的那部分,轻松地设置其他根级对象的初始状态,而不是以前在 INIT_STATE中的状态,但是由于projects已标准化并具有嵌套的子减速器,我不确定如何使用 combineReducers 设置此状态。

所以最终,我希望能够组合减速器,同时处理一个可以覆盖其所有子减速器状态的操作。这是可能的还是有更好的方法来解决这个问题?

非常感谢。

标签: reactjsreduxnormalizrredux-immutable

解决方案


从我看到你想要的是持久化一些保存的状态并将其重新水合到你的减速器状态,Redux persist是专门为此目的而设计的,你可以为每个你想要保存状态的减速器设置一个blacklist或一个whitelist保存状态,这可能会帮助你完成你想要的。

但是,如果您仍然想一次性恢复整棵树的状态,恐怕这可能是不可能的(据我所知),它有点违背 redux 的功能性质(没有副作用),从高级 reducer 修改所有 reducer 的状态是一个很大的副作用,combineReducers只不过是将 reducer 打包成一个捆绑包,但从逻辑上讲,它们都(应该)保持解耦。

话虽这么说,您可以尝试在每个 reducer 处理它之前在中间件中修改您的操作,但是reducer -> catch action -> new state所有 reducer 都获得所有操作的事实是无法解决的,这有点像 redux 试图解决的整个问题,围绕它使库的点无效。


推荐阅读