5

I am using redux-observable and in my epics I am changing the route in some of them using browserHistory.push. Is this standard/good practice? my gut feeling tells no, however need your opinion. In addition to this after upgrading to react-router 4, I cannot get access to browserHistory how do I do this?

tmp dev
  • 8,043
  • 16
  • 53
  • 108

1 Answers1

3

Imperatively calling browserHistory.push() is totally fine. If it works for your use case and you don't need to know about the route changes in your reducers, carry on!

That said, the "purist" way would be for your epic to emit an action that will cause the route change. This can be done in react-router v4 by using the new react-router-redux, which supersedes the old one with the same name.

Once added, you can use the provided actions creators:

import { push } from 'react-router-redux';

export const somethingEpic = action$ =>
  action$.ofType(SOMETHING)
    .switchMap(() => {
      somethingLikeAjaxOrWhatever()
        .mergeMap(response => Observable.of(
          somethingFulfilled(response),
          push('/success-page')
        ))
    });

To be clear, push() replace() etc in react-router-redux are action creators--aka action factories. They don't actually cause the route change themselves, or perform any side effects at all. They return an action that needs to be dispatched somehow for the route to change.


The other benefit of using actions to signal route change intents is testability. You no longer have to mock a history API, you can just assert that the epic emits the expected action. This is known as "effects as data", since your code doesn't perform the actual side effect, you just generate the intent.

jayphelps
  • 15,276
  • 3
  • 41
  • 54
  • I was using react-router-redux however after the package upgrade it ceased to work and the newer version is still beta, so I am a bit hesitant on using it. – tmp dev Oct 11 '17 at 22:59
  • Totally understandable. Unfortunately, right now you have to choose between using react-router@4 and a beta of react-router-redux@5 OR react-router@3 and react-router-redux@4. So you'll have to use react-router@3 if you don't want to use beta of react-router-redux. With either choice, my answer applies as you'll dispatch actions to transition. Btw redux-observable is still beta ;) – jayphelps Oct 12 '17 at 20:38
  • @tmpdev did this answer your question? – jayphelps Oct 20 '17 at 04:48