1. ホーム
  2. javascript

[解決済み】Reduxアプリケーションでコード分割のためにreducersを動的にロードする方法は?

2022-04-16 17:54:10

質問

Reduxに移行しようと思うのですが、どうすればいいですか?

私のアプリケーションは多くのパーツ(ページ、コンポーネント)で構成されているので、多くのreducerを作成したいです。Reduxのサンプルによると、私は combineReducers() を使用して、1 つのレデューサを生成します。

また、私の理解では、Reduxアプリケーションは1つのストアを持つべきで、それはアプリケーションが起動した時点で作成されるものです。ストアが作成されるとき、私は私の結合されたreducerを渡す必要があります。これは、アプリケーションがあまり大きくない場合、理にかなっています。

しかし、複数のJavaScriptバンドルをビルドする場合はどうでしょうか?例えば、アプリケーションの各ページが独自のバンドルを持っている場合です。この場合、1つのreducerを組み合わせるのは良くないと思います。Reduxのソースを見てみると、以下のようなものがありました。 replaceReducer() 関数があります。それは私が欲しいものであるように思われる。

アプリケーションの各部分ごとに結合したreducerを作成し、それを replaceReducer() アプリケーションのパート間を移動するとき。

これは良い方法なのでしょうか?

どのように解決するのですか?

<ブロッククオート

更新情報:こちらもご覧ください ツイッターのやり方 .

これは完全な答えではありませんが、あなたが始めるための助けになるはずです。なお、私は 古いリデューサを捨てない -新しいものを組み合わせリストに追加しているだけです。古いリデューサを捨てる理由はありません。最大のアプリでも、何千もの動的モジュールを持つことはないでしょう。 かもしれない は、アプリケーションの中でいくつかのリデューサを切断したいと思います。

レデューサー.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
  });
}

ストア.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);
      })
    }
  };

  // ...
}

もっときれいな表現があるかもしれませんが、アイデアを示しただけです。