注入 asyncReducers 时的 preloadedState

preloadedState when injecting asyncReducers

怎么可能既有预加载状态(从服务器补水)又动态注入减速器?

react-boilerplate 中有减速器的概念,它是根据您正在查看的 page/components 动态添加的。摘自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的属性名称)

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

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

{ 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);
};