我正在尝试将 redux-saga 集成到我的 React 应用程序中。我目前正在通过在命中正确的路线时使用 ReplaceReducer 动态注入它来进行代码分割减速器。我正在添加一个代码片段。
reducerRegistry.setChangeListener(reducers => {
store.replaceReducer(combine(reducers));
});
我想对传奇做同样的事情,但无法找到动态注入传奇的方法。
我尝试像下面那样实现它,它似乎有效。
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);
});
我只需要在需要时加载 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 }