首页 > 解决方案 > 在使用 redux-observables 和 RxJS 获取史诗期间重定向

问题描述

如果用户无权访问服务器端资源,我有一个 fetch Epic 可能会返回 401 或 403。如果是这种情况,我想在这个 Epic 期间重定向。

现在我正在这样做:

export const fetch$ = <T = any>(req: IRequest) =>
    from(performFetch<T>(req)).pipe(
        switchMap(res => of(res)),
        catchError(e => {
            if (e.status === 401 || e.status === 403) {
                window.location.replace(`/login?fwd=${encodeURIComponent(window.location.pathname)}`);
                return NEVER;
            }
            return of(e);
        })
    );

WhereperformFetch只是一个简单的函数,它执行 fetch 并返回一个 Promise。

我正在使用window.location.replace,到目前为止它工作正常,但有人告诉我它会搞砸 React。

我尝试使用connected-react-router并返回一个push动作,但它没有进行重定向。

我可以安全地继续这样做,还是有更好的方法?

标签: reactjsrxjsreact-routerredux-observableconnected-react-router

解决方案


不需要使用window.location.replaceso ,因为您已安装react-routeror connected-react-router,它处理应用程序中的组件导航。

您可以考虑使用replacepush

如果您希望返回操作,则必须使用of运算符包装它。

import { replace } from 'connected-react-router'.

export const fetch$ = <T = any>(req: IRequest) =>
  from(performFetch<T>(req)).pipe(
    switchMap(res => of(res)),
    catchError(e => {
      if (e.status === 401 || e.status === 403) {
        of(replace(`/login?fwd=${encodeURIComponent(window.location.pathname)}`));
      }
      return of(e);
    })
  );

或者,您可以简单地调用replace/push作为副作用,同时返回其他内容。

export const fetch$ = <T = any>(req: IRequest) =>
  from(performFetch<T>(req)).pipe(
    switchMap(res => of(res)),
    catchError(e => {
      if (e.status === 401 || e.status === 403) {
        replace(`/login?fwd=${encodeURIComponent(window.location.pathname)}`);
        return NEVER;
      }
      return of(e);
    })
  );

推荐阅读