小编典典

如何在 Redux 应用程序中动态加载 reducer 以进行代码拆分?

all

我要迁移到 Redux。

我的应用程序由很多部分(页面、组件)组成,所以我想创建许多减速器。Redux 示例表明我应该使用它combineReducers()来生成一个
reducer。

另外据我了解,Redux 应用程序应该有一个商店,它是在应用程序启动后创建的。创建商店时,我应该通过我的组合减速器。如果应用程序不是太大,这是有道理的。

但是如果我构建了多个 JavaScript 包怎么办?例如,应用程序的每个页面都有自己的捆绑包。我认为在这种情况下,一个组合减速器不好。我查看了 Redux
的源代码,发现了replaceReducer()函数。这似乎是我想要的。

我可以为我的应用程序的每个部分创建组合减速器,并replaceReducer()在我在应用程序的各个部分之间移动时使用。

这是一个好方法吗?


阅读 128

收藏
2022-07-07

共1个答案

小编典典

更新:另请参阅[Twitter 是如何做到](http://nicolasgallagher.com/redux-modules-and-code-

splitting/)的。

这不是一个完整的答案,但应该可以帮助您入门。请注意,我 并没有丢弃旧的减速器 ——只是将新的减速器添加到组合列表中。我认为没有理由丢弃旧的
reducer——即使在最大的应用程序中,您也不太可能拥有数千个动态模块,这就是您 可能 希望在应用程序中断开一些 reducer 的地方。

减速器.js

import { combineReducers } from 'redux';
import users from './reducers/users';
import posts from './reducers/posts';

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

store.js

import { createStore } from 'redux';
import createReducer from './reducers';

export default function configureStore(initialState) {
  const store = createStore(createReducer(), initialState);
  store.asyncReducers = {};
  return store;
}

export function injectAsyncReducer(store, name, asyncReducer) {
  store.asyncReducers[name] = asyncReducer;
  store.replaceReducer(createReducer(store.asyncReducers));
}

路由.js

import { injectAsyncReducer } from './store';

// Assuming React Router here but the principle is the same
// regardless of the library: make sure store is available
// when you want to require.ensure() your reducer so you can call
// injectAsyncReducer(store, name, reducer).

function createRoutes(store) {
  // ...

  const CommentsRoute = {
    // ...

    getComponents(location, callback) {
      require.ensure([
        './pages/Comments',
        './reducers/comments'
      ], function (require) {
        const Comments = require('./pages/Comments').default;
        const commentsReducer = require('./reducers/comments').default;

        injectAsyncReducer(store, 'comments', commentsReducer);
        callback(null, Comments);
      })
    }
  };

  // ...
}

可能有更简洁的方式来表达这个——只是展示这个想法。

2022-07-07