Вы упомянули, что это не идеально, но для тех, кто может не прочитать ваш вопрос, я должен добавить предупреждение, что выполнение этого наводит на мысль, что то, что вы можете делать, является анти-паттерном - но не всегда! Конечно, если вы используете какую-то стороннюю библиотеку, которую не можете контролировать, и вам нужно передать ее ей, это понятный обходной путь. Только не поддавайтесь соблазну постоянно вызывать store.dispatch()
вокруг своих эпосов, так как это, как правило, признак того, что вы боретесь с наблюдаемой редукцией. Конечно, в конце концов, это всего лишь совет, хе-хе:)
ОК. Итак, вот как вы можете это сделать:
redux-observable предоставляет способ внедрить зависимости в каждый epi c. Поэтому, когда вы создаете свое epicMiddleware, вы можете передать ссылку на магазин, отправку или что-либо еще.
https://redux-observable.js.org/docs/recipes/InjectingDependenciesIntoEpics.html
/* Where ever you create your store/middleware
*****************************************/
const middlewares = [];
const epicMiddleware = createEpicMiddleware({
dependencies: {
get store() { // or getStore() if you want
return store;
}
}
});
middlewares.push(applyMiddleware(epicMiddleware));
const store = createStore(
rootReducer,
initialState,
composeEnhancers(...middlewares)
);
epicMiddleware.run(rootEpic);
/* Where ever this epic is
*************************/
const epicDownloadProfile = (action$, state$, { store }) =>
action$.pipe( dependencies ----^
ofType(DOWNLOAD_INIT.getType()),
switchMap(() =>
from(downloadStart(store.dispatch)).pipe(
map(() => DOWNLOAD_INIT()),
catchError((err) => of(DOWNLOAD_ERROR.asError(err.message)))
)
)
);
Есть и другие подходы также, например, экспорт вашего магазина из модуля, импорт его в ваши модули epi c. Но это может быть не очень хорошо, если вам не нужно, чтобы ваш магазин был синглтоном, делая SSR и т. Д. c.
Вот другой подход, если вы предпочитаете его, так как вы всегда должны запускать root epi c после магазин был создан в любом случае.
// Manually inject it yourself by wrapping the "root epic"
// with another function, which is basically an epic which
// defers to your root epic.
epicMiddleware.run((action$, state$) => {
return rootEpic(action$, state$, { store });
});