Multiple Actions one dispatch? #959

Closed
kswope opened this Issue Oct 27, 2015 · 12 comments

Comments

6 participants
@kswope

kswope commented Oct 27, 2015

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!

@nhagen

This comment has been minimized.

Show comment
Hide comment
@nhagen

nhagen Oct 27, 2015

nhagen commented Oct 27, 2015

@jasongonzales23

This comment has been minimized.

Show comment
Hide comment
@jasongonzales23

jasongonzales23 Oct 27, 2015

@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

@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

@kswope

This comment has been minimized.

Show comment
Hide comment
@kswope

kswope Oct 27, 2015

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

store.dispatch([
  {type: PREPOP_DIALOG, value:'me@example.com'}, 
  {type:OPEN_DIALOG, value:true}
])

kswope commented Oct 27, 2015

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

store.dispatch([
  {type: PREPOP_DIALOG, value:'me@example.com'}, 
  {type:OPEN_DIALOG, value:true}
])
@jasongonzales23

This comment has been minimized.

Show comment
Hide comment
@jasongonzales23

jasongonzales23 Oct 27, 2015

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

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

@kswope

This comment has been minimized.

Show comment
Hide comment
@kswope

kswope Oct 27, 2015

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:'me@example.com'})
store.dispatch({type: OPEN_DIALOG, value:true})

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

kswope commented Oct 27, 2015

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:'me@example.com'})
store.dispatch({type: OPEN_DIALOG, value:true})

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

@mindjuice

This comment has been minimized.

Show comment
Hide comment
@mindjuice

mindjuice Oct 27, 2015

Contributor

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 notifications@github.com 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:'me@example.com'})
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.

Contributor

mindjuice commented Oct 27, 2015

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 notifications@github.com 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:'me@example.com'})
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.

@jasongonzales23

This comment has been minimized.

Show comment
Hide comment
@jasongonzales23

jasongonzales23 Oct 27, 2015

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: 'me@example.com'. 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: 'me@example.com' 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.

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: 'me@example.com'. 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: 'me@example.com' 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.

@mindjuice

This comment has been minimized.

Show comment
Hide comment
@mindjuice

mindjuice Oct 27, 2015

Contributor

@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.

Contributor

mindjuice commented Oct 27, 2015

@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.

@jasongonzales23

This comment has been minimized.

Show comment
Hide comment
@jasongonzales23

jasongonzales23 Oct 27, 2015

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?

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?

@mindjuice

This comment has been minimized.

Show comment
Hide comment
@mindjuice

mindjuice Oct 27, 2015

Contributor

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.

Contributor

mindjuice commented Oct 27, 2015

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.

@gaearon

This comment has been minimized.

Show comment
Hide comment
@gaearon

gaearon Oct 27, 2015

Collaborator

The approach we suggest is this: #911 (comment)

Collaborator

gaearon commented Oct 27, 2015

The approach we suggest is this: #911 (comment)

@gaearon gaearon closed this Oct 27, 2015

@gaearon gaearon added the question label Oct 27, 2015

@scozv scozv referenced this issue in scozv/scozv.github.com Mar 10, 2016

Open

a post on How to React a editing form #13

robertleeplummerjr added a commit to robertleeplummerjr/redux that referenced this issue Jun 16, 2016

Addresses #959 without affecting the library's existing functionality…
…. Ultimately tries to prevent re-renders when multiple states are needed in quick succession.
@wikt0r

This comment has been minimized.

Show comment
Hide comment
@wikt0r

wikt0r Dec 15, 2016

Unfortunately the last link is now 404. The good one: #911 (comment)

wikt0r commented Dec 15, 2016

Unfortunately the last link is now 404. The good one: #911 (comment)

@jonaskello jonaskello referenced this issue in redux-loop/redux-loop May 31, 2018

Open

Cmd.action without dispatching #187

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment