redux-observable-envía múltiples acciones redux en una única épica


Estoy buscando la manera de enviar múltiples acciones redux en una única Epic de redux-observable middleware.

Asumamos que tengo siguiente Epic. Cada vez que sucede el evento SEARCH, Epic carga datos del backend y envía la acción RESULTS_LOADED.

searchEpic = (action$) => 
    action$
    .ofType('SEARCH')
    .mergeMap(
        Observable
        .fromPromise(searchPromise)
        .map((data) => {
            return {
                type: 'RESULTS_LOADED',
                results: data
            }
        })
    )

Ahora, supongamos que necesito enviar acción adicional cuando se resuelva el searchPromise.

La forma más sencilla de hacerlo parece tener una segunda epopeya que escuchará RESULTS_LOADED y despachará la segunda acción. Como entonces:

resultsLoadedEpic = (action$) => 
    action$
    .ofType('RESULTS_LOADED')
    .map(({results} => {
         return {
             type: 'MY_OTHER_ACTION',
             results
         } 
    })

En este simple ejemplo es bastante fácil. Pero cuando las epopeyas crecen, tiendo a encontrarme con muchas acciones redux cuyo único propósito es desencadenar otras acciones. Además, parte del código rxjs debe repetirse. Esto me parece un poco feo.

Entonces, mi pregunta: ¿Hay una manera de enviar múltiples acciones redux en una sola épica?

Author: dotintegral, 2016-11-30

1 answers

No hay ningún requisito de que hagas una relación de entrada/salida de uno a uno. Así que puedes emitir múltiples acciones usando mergeMap (también conocido como flatMap) si necesitas:

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))
        ))
    )

Tenga en cuenta que cualquier operador Rx que acepte un Observable también puede aceptar una Promesa, Matriz o Iterable; consumiéndolos como si fueran flujos. Así que podríamos usar una matriz en su lugar para el mismo efecto:

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

El que utilice dependerá de sus preferencias personales de estilo y de su caso de uso.

 23
Author: paulpdaniels,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-01-05 21:11:57