Redux: Multiple Actions one dispatch?

Created on 27 Oct 2015  Â·  12Comments  Â·  Source: reduxjs/redux

Is there currently a way to dispatch multiple actions atomically (is that the right term?). I suppose I mean two or more actions sent in succession which only triggers one component update (but of course multiple mutations to the store).

Normally it looks like middleware would be the place for this to happen, but I don't see how the middleware chain can handle more than one action passing through.

I know I can just call multiple dispatches in succession, but I'm not sure of the race condition implications of this - but I do it anyway :)

Thanks!

question

Most helpful comment

The approach we suggest is this: https://github.com/reactjs/redux/issues/911#issuecomment-149361073

All 12 comments

This is probably better handled by using a more generic action type and
just having more reducers listen to it. If there are mutations that would
also trigger after more specific actions are dispatched you can call
functions that do that mutation in multiple reducers.

@nhagen is correct, but if you really need to chain multiple actions make them "thenable"

dispatch(doThis())
.then(() => dispatch(doThat())

it is also true this would need be in the context of some middleware such as redux-thunk

Let me come at this from another direction, why is this not a good feature?

store.dispatch([
  {type: PREPOP_DIALOG, value:'[email protected]'}, 
  {type:OPEN_DIALOG, value:true}
])

because the dialog may not truly be open yet, I believe you want a promise like thing in this case

OPEN_DIALOG is a signal to open the dialog box.

Something like this works and has proved effective for me

store.dispatch({type: PREPOP_DIALOG, value:'[email protected]'})
store.dispatch({type: OPEN_DIALOG, value:true})

But the problem is it probably triggers an update between the two commands - which goes unnoticed.

See:

https://github.com/acdlite/redux-batched-updates

and also this thread:

https://github.com/rackt/redux/issues/542

Sent from my iPhone

On Oct 26, 2015, at 8:15 PM, Kevin Swope [email protected] wrote:

OPEN_DIALOG is a signal to open the dialog box.

Something like this works and has proved effective for me

store.dispatch({type: PREPOP_DIALOG, value:'[email protected]'})
store.dispatch({type: OPEN_DIALOG, value:true})

But the problem is it probably triggers an update between the two commands - which goes unnoticed.

—
Reply to this email directly or view it on GitHub.

But @kswope for the example you gave I think these batching suggestions are more complexity than you may need unless I misunderstand. Ultimately if you have values that need to be prepopulated you should be updating your store in an action right? So I take issue with type: PREPOP_DIALOG, value: '[email protected]'. It seems semantically imprecise for one thing. Again, this is all shooting from the hip since I only have a small example, but it seems to me that once you have the users email you have an type: ADD_USER_EMAIL, value: '[email protected]' and that ends up being a prop passed down to the modal. Following this thinking you won't need two actions at the moment you want the modal open because the users' email will already be in the store.

@jasongonzales23 My assumption was that his PREPOP_DIALOG was used to make a copy of some data for editing in the dialog, since you need a separate copy for editing purposes (otherwise you are changing the one and only email address and have no ability to Cancel).

Having that as a separate action to make a copy of state for the dialog seems reasonable. You could also use the same action to revert an edit box to its original value if the user clicked a Revert button in the dialog.

Avoiding the intermediate rendering is well with the very minimal extra complexity IMO. You set it up once and then it batches all updates automatically and you forget about it because it works way you expect.

Ah OK, I see. I hadn't thought of it that way, though I wonder if the copy should be made once the user edits?

Sure, your PREPOP_DIALOG reducer could set something like state.dialog.valueBeingEdited to the same reference as the current value, and avoiding making a new copy of the data until it's changed.

To do that though, you would need to pass in with the action payload either a reference to the part of the tree state you want to copy (e.g., a path like ['user', 'email']) or the actual reference already obtained through other means, rather than a raw JS value as shown in the example.

The other way to avoid copying would be to pass in different part of the state tree (as the props of the dialog) depending on whether an edited value had been set via an action yet.

The approach we suggest is this: https://github.com/reactjs/redux/issues/911#issuecomment-149361073

Unfortunately the last link is now 404. The good one: https://github.com/reactjs/redux/issues/911#issuecomment-149361073

Was this page helpful?
0 / 5 - 0 ratings

Related issues

benoneal picture benoneal  Â·  3Comments

jimbolla picture jimbolla  Â·  3Comments

ms88privat picture ms88privat  Â·  3Comments

elado picture elado  Â·  3Comments

jbri7357 picture jbri7357  Â·  3Comments