Redux-Observable 中具有依赖关系的多个操作
Multiple actions with dependencies in Redux-Observable
我在 React & Redux 项目中使用 Redux-Observable Epic。我有多个动作需要发出,原来这是我一直在做的,
1) 在史诗
中抓住START_ACTION
2) 获取远程数据
3) Return 一个新的 Observanble
例如:
import fetch from 'isomorphic-fetch';
import {Observable} from 'rxjs/Observable';
import {switchMap} from 'rxjs/operator/switchMap';
import {mergeMap} from 'rxjs/operator/mergeMap';
const fetchAsync = (arg) => {
// return an observable of promise
return Observable::from(fetch(url + arg));
}
export function myEpic = (action$) => {
action$.ofType(START_ACTION)
::switchMap(action => {
return fetchAsync('/action.payload')
::mergeMap(result => {
return Observable::of({type: ACTION_COMPLETE, payload: result})
})
})
};
现在如果我有另一个动作 SECOND_ACTION
需要在 START_ACTION
之后和 ACTION_COMPLETE
之前发出怎么办?换句话说,如果不确保 SECOND_ACTION
命中减速器,则不应发出 ACTION_COMPLETE
。
我可以编写另一个单独的 Epic 函数来执行此操作,但是还有其他更简单的方法吗?
To simplify the question, I just want to emit the SECOND_ACTION before the async.
要在执行 fetchAsync
之前发出另一个动作,您可以使用 Observable.concat
或 startWith
运算符,这基本上是 concat 的糖分。
export function myEpic = (action$) => {
action$.ofType(START_ACTION)
::switchMap(action => {
return fetchAsync('/action.payload')
::map(result => ({ type: ACTION_COMPLETE, payload: result })
::startWith({ type: SECOND_ACTION })
})
};
因为 SECOND_ACTION
同步跟随 START_ACTION
,请记住,通常你应该让你的 reducer 监听 START_ACTION
而不是发出另一个动作。来自同一个动作的多个 reducer 转换状态是正常的,这也是 redux 的主要好处之一。
也就是说,在某些情况下,关注点分离肯定是更理想的,所以这更像是一个一般性提示。
上一个回答
如果您想按顺序发出两个动作,您可以将附加动作作为参数传递给 Observable.of(...actions)
,因为它接受任意数量的参数并按顺序发出它们。
export function myEpic = (action$) => {
action$.ofType(START_ACTION)
::switchMap(action => {
return fetchAsync('/action.payload')
::mergeMap(result => {
return Observable::of(
{ type: SECOND_ACTION },
{ type: ACTION_COMPLETE, payload: result }
)
})
})
};
如果这不是您的意思,我深表歉意。问题不清楚。
我在 React & Redux 项目中使用 Redux-Observable Epic。我有多个动作需要发出,原来这是我一直在做的,
1) 在史诗
中抓住START_ACTION
2) 获取远程数据
3) Return 一个新的 Observanble
例如:
import fetch from 'isomorphic-fetch';
import {Observable} from 'rxjs/Observable';
import {switchMap} from 'rxjs/operator/switchMap';
import {mergeMap} from 'rxjs/operator/mergeMap';
const fetchAsync = (arg) => {
// return an observable of promise
return Observable::from(fetch(url + arg));
}
export function myEpic = (action$) => {
action$.ofType(START_ACTION)
::switchMap(action => {
return fetchAsync('/action.payload')
::mergeMap(result => {
return Observable::of({type: ACTION_COMPLETE, payload: result})
})
})
};
现在如果我有另一个动作 SECOND_ACTION
需要在 START_ACTION
之后和 ACTION_COMPLETE
之前发出怎么办?换句话说,如果不确保 SECOND_ACTION
命中减速器,则不应发出 ACTION_COMPLETE
。
我可以编写另一个单独的 Epic 函数来执行此操作,但是还有其他更简单的方法吗?
To simplify the question, I just want to emit the SECOND_ACTION before the async.
要在执行 fetchAsync
之前发出另一个动作,您可以使用 Observable.concat
或 startWith
运算符,这基本上是 concat 的糖分。
export function myEpic = (action$) => {
action$.ofType(START_ACTION)
::switchMap(action => {
return fetchAsync('/action.payload')
::map(result => ({ type: ACTION_COMPLETE, payload: result })
::startWith({ type: SECOND_ACTION })
})
};
因为 SECOND_ACTION
同步跟随 START_ACTION
,请记住,通常你应该让你的 reducer 监听 START_ACTION
而不是发出另一个动作。来自同一个动作的多个 reducer 转换状态是正常的,这也是 redux 的主要好处之一。
也就是说,在某些情况下,关注点分离肯定是更理想的,所以这更像是一个一般性提示。
上一个回答
如果您想按顺序发出两个动作,您可以将附加动作作为参数传递给 Observable.of(...actions)
,因为它接受任意数量的参数并按顺序发出它们。
export function myEpic = (action$) => {
action$.ofType(START_ACTION)
::switchMap(action => {
return fetchAsync('/action.payload')
::mergeMap(result => {
return Observable::of(
{ type: SECOND_ACTION },
{ type: ACTION_COMPLETE, payload: result }
)
})
})
};
如果这不是您的意思,我深表歉意。问题不清楚。