【问题标题】:Multiple actions with dependencies in Redux-ObservableRedux-Observable 中具有依赖关系的多个操作
【发布时间】:2018-07-23 05:37:31
【问题描述】:

我在一个 React 和 Redux 项目中使用 Redux-Observable Epic。我有多个动作需要发出,原来这是我一直在做的,

1) 抓住史诗中的 START_ACTION
2) 获取远程数据
3) 返回一个新的 Observanble

例如:

import fetch from 'isomorphic-fetch';
import {Observable} from 'rxjs/Observable';
import {switchMap} from 'rxjs/operator/switchMap';
import {mergeMap} from 'rxjs/operator/mergeMap';


const fetchAsync = (arg) => {
   // return an observable of promise
   return Observable::from(fetch(url + arg));
} 

export function myEpic = (action$) => {
   action$.ofType(START_ACTION)
    ::switchMap(action => {
       return fetchAsync('/action.payload')
          ::mergeMap(result => {
             return Observable::of({type: ACTION_COMPLETE, payload: result})
          }) 
    })
 };

现在,如果我需要在 START_ACTION 之后和 ACTION_COMPLETE 之前发出另一个动作 SECOND_ACTION 怎么办?换句话说,在不确保SECOND_ACTION 命中减速器的情况下,不应该发出ACTION_COMPLETE

我可以编写另一个单独的 Epic 函数来执行此操作,但还有其他更简单的方法吗?

【问题讨论】:

  • ACTION_COMPLETE 操作在等待 SECOND_ACTION 时应该发生什么?如果它永远不会来怎么办?
  • 或者你的意思是你想让这个史诗发射SECOND_ACTION,然后紧跟ACTION_COMPLETE?即发出两个动作
  • 我想发出FIRST_ACTION,然后紧跟SECOND_ACTION。我正在考虑在返回FIRST_ACTION的动作函数中使用dispatch(SECOND_ACTION)
  • FIRST_ACTION 来自哪里?这不在你上面​​的问题中。你是说ACTION_COMPLETE吗?

标签: javascript react-redux rxjs5 redux-observable


【解决方案1】:

为了简化问题,我只想在异步之前发出 SECOND_ACTION。

要在执行fetchAsync 之前发出另一个动作,您可以使用Observable.concatstartWith 运算符,这基本上是concat 的糖。

export function myEpic = (action$) => {
   action$.ofType(START_ACTION)
    ::switchMap(action => {
       return fetchAsync('/action.payload')
          ::map(result => ({ type: ACTION_COMPLETE, payload: result })
          ::startWith({ type: SECOND_ACTION })
    })
 };

由于SECOND_ACTION 同步跟随START_ACTION,请记住,您通常应该让您的reducer 只听START_ACTION 而不是发出另一个动作。多个 reducer 从同一个 action 转换状态是正常的,这是 redux 的主要好处之一。

也就是说,在某些时候关注点分离肯定更理想,所以这是一个更一般的提示。


上一个答案

如果您想按顺序发出两个动作,您可以将附加动作作为参数传递给Observable.of(...actions),因为它接受任意数量的参数并按顺序发出。

export function myEpic = (action$) => {
   action$.ofType(START_ACTION)
    ::switchMap(action => {
       return fetchAsync('/action.payload')
          ::mergeMap(result => {
             return Observable::of(
               { type: SECOND_ACTION },
               { type: ACTION_COMPLETE, payload: result }
             )
          }) 
    })
 };

如果这不是你的意思,我很抱歉。问题不清楚。

【讨论】:

  • 感谢您的回答,对于不清楚的问题深表歉意。 FIRST_ACTION 来自用户触发的动作文件。例如,您可以将其想象为单击表单中的submit 按钮引起的动作。这将向reducer 发出一个动作来更新state,说“嘿,我正在向数据库提交一些东西(异步)”。 React 将根据状态变化显示加载微调器。
  • 为了简化问题,我只想在异步之前发出SECOND_ACTION
猜你喜欢
  • 1970-01-01
  • 2018-01-24
  • 2020-05-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多