Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Where to dispatch multiple actions in redux?

I am using redux with connect and redux-thunk middleware and containers.

Currently when an user perform an action, example one click on a button, I need to dispatch that action (sync) which will dispatch other few actions (asynch).

I am aware dispatching actions from within the reducer is an anti pattern.

I would like to know what is a suitable place for this code.

Currently I am not sure if it should stay in:

  • The action creator.
  • In the container using store.subscribe.
like image 297
Radex Avatar asked Jun 02 '17 05:06

Radex


3 Answers

The recommended way as per the documentation is in the action creator, like so:

function actionCreator(payload) {
    return dispatch => {
        dispatch(action1(payload))
        dispatch(action2(payload))
    }
}

Then you would probably want to attach the action creators as prop and pass it down to the container using mapDispatchToProps like in the example mentioned here. So it would look something like so:

const mapDispatchToProps = dispatch => ({
   action1: some_payload => dispatch(action1(some_payload))
   action2: some_payload => dispatch(action2(some_payload))
})

// your component
export default connect(mapStateToProps, mapDispatchToProps)(YourApp)

like image 112
Mμ. Avatar answered Oct 12 '22 01:10

Mμ.


As other pointed out The action creator is the right place for dispatching multiple actions.

Below an example of how action1 could dispatch other actions in your action creator.

const action1 = id => {
  return dispatch => {
    dispatch(action2(id))
    dispatch(action3(id))
  }
}
like image 39
GibboK Avatar answered Oct 12 '22 02:10

GibboK


The action creator is the correct location for dispatching multiple actions. Although code like the following would work:

function actionCreator(payload) {
    return dispatch => {
        dispatch(action1(payload))
        dispatch(action2(payload))
    }
}

I would highly recommend redux-thunk based action creators to always return a resolved Promise, so that such action creators can be part of another async call. So, the simplest update to the above would be:

function actionCreator(payload) {
    return dispatch => {
        dispatch(action1(payload));
        dispatch(action2(payload));
        return Promise.resolve();
    }
}

It would then be possible to dispatch to the above with: actionCreator(payload).then(doAnotherAction(anotherPayload)) or the following, if we need to maintain order of calls: actionCreator(payload).then(() => doAnotherAction(anotherPayload))

If you wish to 'future-proof' your action creator, so that it could handle calling both async and sync action creators, you could write it as:

function actionCreator(payload) {
    return dispatch =>
        Promise.resolve(dispatch(action1(payload))).then(
        () => dispatch(action2(payload)));
}

And, if you like ES6 arrow notation the above can be defined as:

const actionCreator = payload => dispatch =>
        Promise.resolve(dispatch(action1(payload))).then(
        () => dispatch(action2(payload)));
like image 41
Shiraz Avatar answered Oct 12 '22 01:10

Shiraz