首页 > 解决方案 > 注入 asyncReducers 时的 preloadedState

问题描述

怎么可能同时拥有 preloadedState(从服务器补水)和动态注入减速器?

react-boilerplate如何在 Redux 应用程序中动态加载减速器以进行代码拆分?根据您正在查看的页面/组件,动态添加减速器的概念。摘自reducers.js

export default function createReducer(asyncReducers) {
  return combineReducers({
    users,
    posts,
    ...asyncReducers
  });
}

虽然这在从一个页面导航到另一个页面(或仅在客户端应用程序上)时效果很好;当从服务器补水数据时,我遇到了这个错误:

Unexpected property "comments" found in previous state received by the reducer. Expected to find one of the known reducer property names instead: "users", "posts". Unexpected properties will be ignored.

comments动态注入reducer的属性名在哪里)

这个错误的原因很清楚,因为preloadedState来自服务器的(使用 React SSR)已经包含comments并且初始 reducer 没有,因为这是之后动态添加的。如果我添加comments到我的combineReducers;错误就会消失 但这意味着在应用程序初始化时,我需要包含所有减速器;这并不理想。

标签: reactjsreduxreact-boilerplate

解决方案


您应该能够使用虚拟减速器代替动态加载的减速器,动态加载的减速器将在加载真正的减速器时被替换。

{ comments: (state = null) => state }

这也可以自动完成,具体取决于您的实现,根据http://nicolasgallagher.com/redux-modules-and-code-splitting/

// Preserve initial state for not-yet-loaded reducers
const combine = (reducers) => {
  const reducerNames = Object.keys(reducers);
  Object.keys(initialState).forEach(item => {
    if (reducerNames.indexOf(item) === -1) {
      reducers[item] = (state = null) => state;
    }
  });
  return combineReducers(reducers);
};

推荐阅读