最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to perform side-effect inside of an epic in redux-observable? - Stack Overflow

programmeradmin0浏览0评论

In redux-observable, epics are accepting stream of actions and returning back new stream of actions. In my use-case I need to send analytics event after some action was dispatched and do nothing after.

With redux-saga, I can just listen that action using takeEvery, and perform a side-effect inside of a saga function:

function* saga() {
  yield takeEvery('SOME_ACTION', function*() {
    sendAnalytics();
  })
}

But how can I achieve the same with redux-observable? There is pretty much side effects, that are not requiring dispatching new actions, like initializing plugins, logging, setting cookies etc...

If it's an anti-pattern for both of these libraries, what solution should be used for these kinds of effects?

In redux-observable, epics are accepting stream of actions and returning back new stream of actions. In my use-case I need to send analytics event after some action was dispatched and do nothing after.

With redux-saga, I can just listen that action using takeEvery, and perform a side-effect inside of a saga function:

function* saga() {
  yield takeEvery('SOME_ACTION', function*() {
    sendAnalytics();
  })
}

But how can I achieve the same with redux-observable? There is pretty much side effects, that are not requiring dispatching new actions, like initializing plugins, logging, setting cookies etc...

If it's an anti-pattern for both of these libraries, what solution should be used for these kinds of effects?

Share Improve this question edited Aug 9, 2017 at 23:54 jayphelps 15.4k3 gold badges44 silver badges55 bronze badges asked Aug 9, 2017 at 10:33 1ven1ven 7,0261 gold badge28 silver badges39 bronze badges 2
  • I haven't used either redux-saga or redux-observable, but I've done this particular side effect of tracking by just calling the analytics module inside of mapDispatchToProps, which is a legitimate place to do this in my opinion. So before or after you call dispatch you just do something like googleAnalytics.trackEvent(...). – timotgl Commented Aug 9, 2017 at 11:18
  • Thanks, but in my opinion, mapDispatchToProps functions is not the right place to perform side-effects – 1ven Commented Aug 10, 2017 at 6:53
Add a comment  | 

1 Answer 1

Reset to default 22

Definitely not an anti-pattern outright to have an epic which is "read-only"--but I want to caution that it's often a sign a person is doing something less-than-idiomatic, but this is not one of those cases.

There are likely many ways of accomplishing this in Rx. Here are two:

do + ignoreElements

I think this is the most clear of what it does. do is only ever used to perform a side effect (often logging) for next/error/complete without affecting the stream. We then use ignoreElements to prevent the SOME_ACTION from being dispatched again (which would cause infinite recursion). See the rxjs docs for more info on these operators

const someEpic = action$ =>
  action$.ofType('SOME_ACTION')
    .do(() => sendAnalytics())
    .ignoreElements();

Anonymous Observable

This is a somewhat more "lightweight" solution since it doesn't use any operators other than ofType. I would caution against using this one though until you and your teammates have a solid grasp of RxJS and particularly creating custom/anonymous Observables. i.e. don't write code you don't understand.

const someEpic = action$ =>
  new Observable(() =>
    action$.ofType('SOME_ACTION')
      .subscribe(() => sendAnalytics()) // subscription is returned so it can be cleaned up
  );

This use case would be a great addition to the Recipes section of the docs, if someone ever has the time to PR it.


Btw, this is mostly an RxJS question where the stream just happens to be actions. You might find you get answers and better support long-term if you search or phrase your questions in the context of RxJS instead of redux-observable. Nearly all redux-observable questions are actually RxJS questions, which is great cause the knowledge is transferable!

发布评论

评论列表(0)

  1. 暂无评论