如何在组件中订阅epic的动作输出流

时间:2018-08-16 14:45:35

标签: redux redux-observable

我正在将loadInstruments重构为Redux可观察的史诗,因为它正在做越来越多的异步事情,而且我需要取消动作(来自教程的典型Wiki搜索场景)。

这就是我的组件使用此thunk的方式(可通过mapDispatchToProps使用它)

this.props.loadInstruments(queryParams).then(...)

Thunk正在做很多事情,其中​​之一是AJAX调用。它返回了一个我可以等待然后查看AJAX调用结果的承诺(该结果也已放入redux存储中)。

但是,在重构为redux-observable和史诗之后,由于我的loadInstruments看起来像这样(它只是调度和操作,而史诗的ofType正在过滤,因此我无法从史诗中返回值) ):

const loadInstruments = ({ type: 'LAUNCH_LOAD_INSTRUMENTS_EPIC' })

LAUNCH_LOAD_INSTRUMENTS_EPICofType捕获时,它与rxjs magic一起运行,并且一旦加载了工具(AJAX调用),它们最终就会存储在商店中(通过使用switchMap并分派新的更新商店的操作)。

但是我的组件正在使用loadInstruments返回的Promise结算值来快速获取所获取的/放入商店的东西。重构为史诗之后,我不知道如何从loadInstument获取/返回值。

是否有一种方法可以实现与redux-observable类似的功能,或者我需要重构组件?例如

loadInstruments(queryParams).subscribe(x => ...)

1 个答案:

答案 0 :(得分:1)

我对redux-thunk不太熟悉,但是如果我理解正确,以前的thunk正在更新组件状态或应用程序(redux)状态。重构为使用redux-observable时,您将不再获得组件的更新值。

这听起来像您只需要使用redux connect(mapState, mapDispatch)来订阅组件内部的状态更改 在这种情况下,mapDispatch将包装loadInstruments,我相信您已经在使用它,并且mapState将订阅您从史诗中调度动作后更新的状态。 您只需要确保您的史诗“退出”操作包括用于更新Redux状态的数据,并且您还已订阅组件中的状态更改。例如

const myEpic = (action$) => 
action$.pipe(
  ofType(LAUNCH_LOAD_INSTRUMENTS_EPIC),
  /* ajax operators and whatever else*/
  mapTo({ type: OUT_ACTION_WITH_NEW_STATE instruments: {/*new state*/} })
)

/*reducer land...*/
if (action.type === OUT_ACTION_WITH_NEW_STATE) {
  return {...prevState, instruments: action.instruments}
}

/*component land*/
connect((state) => {instruments: state.instruments}, {loadInstruments})(myComponent)

要引用您的问题的标题“订阅组件中史诗的动作输出流”,您不需要。订阅发生在可观看Redux的中间件中。因此,您无需手动将subscribe()调用添加到流的末尾。通过redux-observable,操作流程为:

发送动作->减速器->史诗->动作->减速器->史诗->动作...(重复) 如果有任何组件使用connect订阅了redux存储,则在更新存储时,该组件将以prop的形式接收更新后的状态。