首页 文章

注入 asyncReducers 时的 preloadedState

提问于
浏览
0

如何同时拥有 preloadedState(从服务器保湿)和动态注入 Reducer?

react-boilerplate如何为 Redux 应用程序中的代码拆分动态加载 reducers?中有减速器的概念,它是根据您正在查看的 page/components 动态添加的。从reducers.js中提取:

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

虽然这在从一个页面导航到另一个页面时(或仅在 client-side 应用程序上)很有效;当从服务器保湿数据时,我遇到了这个错误:

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,则错误消失;然而,这意味着在 app 初始化时我需要包括所有减速器;这不是理想的。

1 回答

  • 1

    您应该能够使用虚拟减速器代替动态加载的减速器,这些减速器将在加载实际减速器时进行替换。

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

相关问题