在Redux Observable/RxJS中,如何发出动作和助手函数的组合
用户通过身份验证后,我需要调用2个函数(在Redux Observable/RxJS中,如何发出动作和助手函数的组合,rxjs,redux-observable,Rxjs,Redux Observable,用户通过身份验证后,我需要调用2个函数(AsyncStorage.setItem和setapiaAuthorization),然后调用2个redux操作(LOAD\u user和SET\u SESSION\u user)。根据下面的尝试,我将如何实现这一点?或者我也应该为这两个函数创建redux操作 const loginUserEpic = (action$, state$) => action$.pipe( ofType('LOGIN_USER'), mergeMa
AsyncStorage.setItem
和setapiaAuthorization
),然后调用2个redux操作(LOAD\u user
和SET\u SESSION\u 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\u令牌之后,它将包含在任何后续api调用的头中。因此,我需要确保在调用作为api调用的LOAD\u USER
之前保存id\u令牌
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))
)
)
);
设置会话存储是一个副作用。
所以最好在一个
您的epic应该只将动作作为输出返回(动作输入、动作输出)。如果您这样做,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))
)
)
)
另一个简单的方法是使用switchMap
switchMap(() => [
{
type: 'LOAD_USER',
},
{
type: 'SET_SESSION_USER',
user: response.data.user,
}
])
只要结果是一个数组,它就会自动将结果包装成可观察值。因此,您不再需要of()
它。我在项目中经常使用它。谢谢。请问,在调用mergeMap
之前,点击是否完成?在LOAD\u USER
操作中需要保存到存储中的id\u令牌
,因此我需要确保在调用LOAD\u USER
@theseboys之前始终保存该令牌。tap
不能保证在mergeMap
启动之前完成。为了实现这种行为,您需要将AsyncStorage.setItem
包装在一个可观察的文件中。但不管怎样,我认为访问reducer中的存储
不是一个好主意,因为你会给你的reducer带来副作用,这应该是纯的。更好的方法是将响应传递给您的操作{type:'LOAD\u USER'}
,并在减速器中使用它,而不引入副作用。谢谢。我在开场白中添加的最新史诗看起来如何?