redux-observable - envoi de plusieurs redux actions dans une seule epic
je cherche un moyen d'envoyer plusieurs actions redux dans une seule épopée de redux-observable
middleware.
supposons que j'ai l'épopée suivante. A chaque fois que SEARCH
événement se produit, Épique charge les données à partir du backend et distribue RESULTS_LOADED
action.
searchEpic = (action$) =>
action$
.ofType('SEARCH')
.mergeMap(
Observable
.fromPromise(searchPromise)
.map((data) => {
return {
type: 'RESULTS_LOADED',
results: data
}
})
)
maintenant, supposons que j'ai besoin d'une action supplémentaire d'expédition lorsque le searchPromise
est résolu.
la façon la plus simple de le faire semble avoir une deuxième épopée qui écoutera RESULTS_LOADED
et d'envoyer le la seconde action. Comme ceci:
resultsLoadedEpic = (action$) =>
action$
.ofType('RESULTS_LOADED')
.map(({results} => {
return {
type: 'MY_OTHER_ACTION',
results
}
})
Dans cet exemple simple, c'est assez facile. Mais quand les épopées grandissent, j'ai tendance à me trouver avec beaucoup d'actions redux dont le seul but est de déclencher d'autres actions. De plus, certains codes rxjs doivent être répétés. Je trouve que c'est un peu moche.
alors, ma question: y a-t-il un moyen d'envoyer plusieurs actions redux dans une seule épopée?
1 réponses
il n'y a aucune exigence que vous fassiez un rapport d'entrée/sortie de un à un. Ainsi, vous pouvez émettre plusieurs actions en utilisant mergeMap
(aka flatMap
) si vous avez besoin de:
const loaded = (results) => ({type: 'RESULTS_LOADED', results});
const otherAction = (results) => ({type: 'MY_OTHER_ACTION', results});
searchEpic = (action$) =>
action$
.ofType('SEARCH')
.mergeMap(
Observable
.fromPromise(searchPromise)
// Flattens this into two events on every search
.mergeMap((data) => Observable.of(
loaded(data),
otherAction(data))
))
)
notez que tout opérateur Rx qui accepte un Observable peut aussi accepter une promesse, un tableau, ou itérable; les consommant comme-s'ils étaient des flux. Nous pourrions donc utiliser un tableau pour le même effet:
.mergeMap((data) => [loaded(data), otherAction(data)])
celui que vous utilisez dépend de vos préférences personnelles de style et cas d'utilisation.