如何在 Redux 应用程序中动态加载 reducer 以进行代码拆分? [英] How to dynamically load reducers for code splitting in a Redux application?

查看:16
本文介绍了如何在 Redux 应用程序中动态加载 reducer 以进行代码拆分?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我要迁移到 Redux.

I'm going migrate to Redux.

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

My application consists of a lot of parts (pages, components) so I want to create many reducers. Redux examples show that I should use combineReducers() to generate one reducer.

此外,据我所知,Redux 应用程序应该有一个存储区,并且在应用程序启动后创建.创建商店时,我应该通过我的组合减速器.如果应用程序不是太大,这很有意义.

Also as I understand Redux application should have one store and it is created once the application starts. When the store is being created I should pass my combined reducer. This makes sense if the application is not too big.

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

But what if I build more than one JavaScript bundle? For example, each page of application has own bundle. I think in this case the one combined reducer is not good. I looked through the sources of Redux and I have found replaceReducer() function. It seems to be what I want.

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

I could create combined reducer for each part my application and use replaceReducer() when I move between parts of application.

这是一个好方法吗?

推荐答案

更新:另请参阅Twitter 的做法.

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

This is not a full answer but should help you get started. Note that I'm not throwing away old reducers—I'm just adding new ones to the combination list. I see no reason to throw away the old reducers—even in the largest app you're unlikely to have thousands of dynamic modules, which is the point where you might want to disconnect some reducers in your application.

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

routes.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);
      })
    }
  };

  // ...
}

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

There may be neater way of expressing this—I'm just showing the idea.

这篇关于如何在 Redux 应用程序中动态加载 reducer 以进行代码拆分?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆