如何从redux-observables中的epic访问调度功能

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

我想知道是否有必要从redux-observables(1.2)中的史诗中访问redux的dispatch函数。

export const epicDownloadProfile = (action$, { dispatch }) =>
  action$.pipe(
    ofType(DOWNLOAD_INIT.getType()),
    switchMap(() =>
      from(downloadStart(dispatch)).pipe(
        map(() => DOWNLOAD_INIT()),
        catchError(err => of(DOWNLOAD_ERROR.asError(err.message)))
      )
    )
  )

我知道这并不理想,但是我有一个非常复杂的功能,在下载时会产生很多事情,因此我需要将dispatch传递给downloadStart()。Redux-observables为我提供了StateObservable对象作为史诗的第二个参数,它确实包含状态,但不包含调度功能...在示例中,{ dispatch }来自undefined。我还有其他访问方式吗?

redux-observable
1个回答
1
投票

您确实提到这不是理想的选择,但是对于可能看不懂您问题的其他人,我必须添加警告,指出这样做可能暗示您可能正在做的是反模式,但并非总是如此!当然,如果您使用的是您无法控制的某种第三方库,并且需要将其传递给它,那么这是可以理解的解决方法。只是不要太想经常在您的Epics周围打store.dispatch(),因为这通常是您在应对redux可观察到的信号。当然,归根结底,这只是建议而已:)

确定。因此,这是您的操作方法:

redux-observable提供了一种将依赖项注入每个史诗的方法。因此,当您创建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)))
      )
    )
  );

还有其他方法,例如从模块中导出商店,将其导入到史诗模块中。但是如果您不想让您的商店成为单身人士,进行SSR等操作,那可能就不好了。

如果您愿意,这是另一种方法,因为您应该始终启动根史诗之后无论如何,商店已经创建。

// 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 });
});
© www.soinside.com 2019 - 2024. All rights reserved.