redux-observable 调度动作 [英] redux-observable dispatch actions

查看:53
本文介绍了redux-observable 调度动作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要使用 redux-observable 以某种顺序分派一些动作,但是,它只需要分派最后一个动作.请看例子:

I need to dispatch some actions in some order using redux-observable however, it takes just last action to dispatch. Please see example:

export const fetchClientsEpic = (action$, { dispatch }) =>
  action$
    .ofType(fetchClients)
    .mapTo(fetchClientsPending(true))
    .mergeMap(() => {
      return ajax
        .getJSON('some/get/clients/api')
        .map((clients: IClient[]) => {
          return fetchClientsSuccess(
            map(clients, (client, index) => ({
              key: index,
              ...client,
            })),
          );
        });
    });

fetchClientsSuccess 与客户端一起发送,但 fetchClientsPending 不是,我完全不明白为什么.我可以使用 dispatch 因为我在参数中得到它,但我觉得这不是一个好的解决方案(?).我猜它应该在流中完成.我从 RxJs 和 redux-observable 开始.有可能吗?

fetchClientsSuccess is dispatched with clients but fetchClientsPending not, I totally do not get it why. I could use dispatch because I get it in params, but I feel it is not good solution(?). It should be done in the stream I guess. I am starting with RxJs and redux-observable. Is it possible to do?

推荐答案

Operators 是 Observables 链,其中一个流的输入是另一个流的输出.因此,当您使用 mapTo 时,您将一个操作映射到另一个操作.但是随后您的 mergeMap 映射该 Pending 操作并将其映射到执行 ajax 等操作的其他内部 Observable,从而有效地丢弃 Pending 操作.因此,将 RxJS 视为数据流经的一系列管道(流)

Operators are chains of Observables where the input of one stream is the output of another. So when you use mapTo you're mapping one action to the other. But then your mergeMap maps that Pending action and maps it to that other inner Observable that does the ajax and such, effectively throwing the Pending action away. So think of RxJS as a series of pipes where data flows through (a stream)

虽然没有灵丹妙药,但在这种特殊情况下,您可以通过在内部 Observable 的末尾使用 startWith 来完成您想要实现的目标

While there is no silver bullet, in this particular case what you want to achieve can be done by using startWith at the end of your inner Observable

export const fetchClientsEpic = (action$, { dispatch }) =>
  action$
    .ofType(fetchClients)
    .mergeMap(() => {
      return ajax
        .getJSON('some/get/clients/api')
        .map((clients: IClient[]) => {
          return fetchClientsSuccess(
            map(clients, (client, index) => ({
              key: index,
              ...client,
            })),
          );
        })
        .startWith(fetchClientsPending(true)); // <------- like so
    });

这实际上与使用 concatof(action) first 相同,只是速记.

This is in fact the same thing as using concat with of(action) first, just shorthand.

export const fetchClientsEpic = (action$, { dispatch }) =>
  action$
    .ofType(fetchClients)
    .mergeMap(() => {
      return Observable.concat(
        Observable.of(fetchClientsPending(true)),
        ajax
          .getJSON('some/get/clients/api')
          .map((clients: IClient[]) => {
            return fetchClientsSuccess(
              map(clients, (client, index) => ({
                key: index,
                ...client,
              })),
            );
          })
      );
    });

<小时>

也就是说,我建议不要同步调度另一个动作来设置获取挂起的状态,而是依靠原始的 fetchClients 动作本身来达到相同的效果.您的减速器应该假设,如果看到这样的动作,那么无论如何获取仍然会开始.这为您节省了样板文件并有助于微性能,因为您不需要运行减速器、史诗和重新渲染两次.


That said, I would recommend against synchronously dispatching another action to set the state that fetching is pending and instead rely on the original fetchClients action itself for the same effect. It should be assumed by your reducers that if such an action is seen, that some how the fetching still start regardless. This saves you the boilerplate and helps a bit on micro-perf since you don't need to run through the reducers, epics, and rerender twice.

虽然没有规则,所以如果你对此有强烈的感觉,那就去做吧:)

There's no rules though, so if you feel strongly about this, go for it :)

这篇关于redux-observable 调度动作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆