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?

23
demandé sur dotintegral 2016-11-30 14:02:07

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.

23
répondu paulpdaniels 2018-01-05 21:11:57