在Redux-Observable / RxJS中,如何发出动作和辅助函数的组合

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

在用户通过身份验证后,我需要调用2个函数(AsyncStorage.setItemsetAPIAuthorization),然后调用2个redux动作(LOAD_USERSET_SESSION_USER)。我将如何根据以下尝试实现此目标?或者我应该为这两个函数创建redux动作吗?

const loginUserEpic = (action$, state$) =>
  action$.pipe(
    ofType('LOGIN_USER'),
    mergeMap(() =>
      from(axios.post(`/auth`, {})).pipe(
        mergeMap(response =>
          of(
            AsyncStorage.setItem('id_token', response.data.token),
            setAPIAuthorization(response.data.token),
            {
              type: 'LOAD_USER'
            },
            {
              type: 'SET_SESSION_USER',
              user: response.data.user
            }
          )
        ),
        catchError(error => console.log(error))
      )
    )
  );

感谢下面的Anas,这是我用来实现我想要的更新。到目前为止成功。在我存储id_token后,它包含在任何后续api调用的标头中。出于这个原因,我需要确保在调用id_token之前保存LOAD_USER,这是一个api调用。

const loginUserEpic = (action$, state$) =>
  action$.pipe(
    ofType('LOGIN_USER'),
    mergeMap(() =>
      from(axios.post(`/auth`, {})).pipe(
        mergeMap(response => {
          return new Observable(observer => {
            AsyncStorage.setItem('id_token', response.data.token);
            setAPIAuthorization(response.data.token);
            observer.next(
              {
                type: 'LOAD_USER'
              },
              {
                type: 'SET_SESSION_USER',
                user: response.data.user
              }
            );
          });
        }),
        catchError(error => console.log(error))
      )
    )
  );
rxjs redux-observable
2个回答
1
投票

设置会话存储是一个副作用。所以在tap做得更好,

你的史诗只应该将动作作为输出返回(动作输入,动作输出)。如果你这样做,redux会抱怨你没有返回简单的行动。

我仍然会为{ type: 'LOAD_USER' }{ type: 'SET_SESSION_USER'}创建动作创建者,因为它更干净。

const loginUserEpic = (action$, state$) =>
  action$.pipe(
    ofType('LOGIN_USER'),
    mergeMap(() =>
      from(axios.post('/auth', {})).pipe(
        tap((response) => {
          AsyncStorage.setItem('id_token', response.data.token)
          setAPIAuthorization(response.data.token)
        }),
        mergeMap(response =>
          of(
            {
              type: 'LOAD_USER',
            },
            {
              type: 'SET_SESSION_USER',
              user: response.data.user,
            }
          )
        ),
        catchError(error => console.log(error))
      )
    )
  )

0
投票

另一个简单的方法是使用switchMap

switchMap(() => [
  {
    type: 'LOAD_USER',
                },
  {
    type: 'SET_SESSION_USER',
    user: response.data.user,
  }
])

只要它是一个数组,它就会自动将结果包装到observable中。所以你不再需要of()了。我在我的项目中使用了很多。

© www.soinside.com 2019 - 2024. All rights reserved.