动态加载 sagas 以在 Redux 应用程序中进行代码分割

问题描述 投票:0回答:2

我正在尝试将 redux-saga 集成到我的 React 应用程序中。我目前正在通过在命中正确的路线时使用 ReplaceReducer 动态注入它来进行代码分割减速器。我正在添加一个代码片段。

reducerRegistry.setChangeListener(reducers => {
    store.replaceReducer(combine(reducers));
});

我想对传奇做同样的事情,但无法找到动态注入传奇的方法。

reactjs redux redux-saga
2个回答
4
投票

我尝试像下面那样实现它,它似乎有效。

export class SagaRegistry {
  constructor() {
    this._emitChange = null;
    this._sagas = {};
  }

  getSagas() {
    return { ...this._sagas };
  }

  register(name, saga) {
    if (this._sagas[name]) {
      return;
    }
    this._sagas = { ...this._sagas, [name]: saga };
    if (this._emitChange) {
      this._emitChange(saga);
    }
  }

  setChangeListener(listener) {
    this._emitChange = listener;
  }
}

const sagaRegistry = new SagaRegistry();
export default sagaRegistry;

然后像这样运行传奇。

sagaRegistry.setChangeListener(saga => {
  sagaMiddleware.run(saga);
});

0
投票

我只需要在需要时加载 sagas,并且在导入过程中不会丢失任何操作。

function* lazyLoader(actionTypePrefixes: string[], sagaImport: () => Promise<{ default: any }>) {
  const actionPatternMatcher = (a: abstractAction) => actionTypePrefixes.some((prefix) => a.type.startsWith(prefix))
  const queue: abstractAction[] = [yield take(actionPatternMatcher)]

  const taskListener: Task = yield takeEvery(actionPatternMatcher, (action) => queue.push(action))

  const importedSaga = (yield sagaImport()).default

  while (queue.length) {
    const action = queue.shift()
    if (importedSaga.coldBootInitializer) {
      yield call(importedSaga.coldBootInitializer, action)
    }
  }

  yield taskListener.cancel()

  if (importedSaga?.run) {
    yield fork(importedSaga.run)
  }
}

// Root saga is using this
export function* analyticsLazyLoader() {
  yield* lazyLoader(['analytics/'], () => import('./analytics.saga'))
}

同时,导入的传奇看起来像这样

function* analyticsSaga() {
  yield takeLeading(ANALYTICS_ACTIONS_TYPES.TRACK_PAGEVIEW_EVENT, anySaga1)
  yield takeEvery(ANALYTICS_ACTIONS_TYPES.TRACK_ECOMMERCE_EVENT_REF, anySaga2)
}

function* coldBootInitializer(initAction?: analyticsInitActionType) {
  if (initAction) {
    switch (initAction.type) {
      case ANALYTICS_ACTIONS_TYPES.TRACK_PAGEVIEW_EVENT:
        yield call(anySaga1, initAction)
        break

      case ANALYTICS_ACTIONS_TYPES.TRACK_ECOMMERCE_EVENT_REF:
        yield call(anySaga2, initAction)
        break
    }
  }
}

export default { run: analyticsSaga, coldBootInitializer }
© www.soinside.com 2019 - 2024. All rights reserved.