47 votes

redux-observable - envoie plusieurs actions redux en une seule épopée

Je suis à la recherche de la manière de l'expédition de plusieurs redux actions dans une seule Épopée de l' redux-observable middleware.

Supposons que j'ai suivantes Épique. 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 de l'expédition des mesures supplémentaires lors de l' searchPromise est résolu.

La façon la plus simple de le faire semble avoir une seconde épopée qui sera à l'écoute de RESULTS_LOADED et expédition de la deuxième action. Comme suit:

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 de grandir, j'ai tendance à trouver moi-même avoir beaucoup de redux actions dont le seul but est de déclencher d'autres actions. En outre, certains de rxjs code doit être répétée. Je trouve que c'est un peu moche.

Donc, ma question: Est-il un moyen de l'expédition de plusieurs redux actions dans une seule Epic?

58voto

paulpdaniels Points 12976

Il n'est pas nécessaire de faire un one-to-one in/out ratio. Donc, vous pouvez émettre des actions multiples à l'aide de 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))
        ))
    )

À noter que toute Rx opérateur qui accepte un Observable peut également accepter une Promesse, Tableau, ou Itératif; de les consommer comme si ils étaient des ruisseaux. Nous avons donc pu utiliser un tableau à la place pour le même effet:

.mergeMap((data) => [loaded(data), otherAction(data)])

Celui que vous utilisez dépend de votre style personnel, les préférences et les cas d'utilisation.

3voto

Qiang Points 3

Ou peut-être que vous avez trois actions,

API_REQUEST, API_RUNNING, API_SUCCESS,

 searchEpic = (action$) => 
action$
.ofType('API_REQUEST')
.mergeMap((action) => {
   return concat(
       of({type: 'API_RUNNING'}),
       Observable.fromPromise(searchPromise)
        .map((data) => {
          return {type: 'API_SUCCESS', data}; 
        }),
    );
});
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X