用户通过身份验证后,我需要调用2个函数(AsyncStorage.setItem
和setAPIAuthorization
),然后调用2个redux操作(LOAD_USER
和SET_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
这是一个api调用之前,我需要确保LOAD_USER
已保存。
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))
)
)
);
答案 0 :(得分: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))
)
)
)
答案 1 :(得分:0)
另一种简单的方法是使用switchMap
switchMap(() => [
{
type: 'LOAD_USER',
},
{
type: 'SET_SESSION_USER',
user: response.data.user,
}
])
只要是数组,它就会自动将结果包装到可观察对象中。因此,您不再需要of()
。我在项目中经常使用它。