Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Batching actions #911

Closed
tshelburne opened this issue Oct 18, 2015 · 13 comments
Closed

Batching actions #911

tshelburne opened this issue Oct 18, 2015 · 13 comments

Comments

@tshelburne
Copy link

I needed to be able to mark specific actions as "skipped" so that a larger action could encapsulate smaller ones without notifying subscribers of incoherent state. I created redux-skip-by-action for this purpose - unit tests are pending, QA tests passing, and any feedback would be really appreciated.

Thanks.

@gaearon
Copy link
Contributor

gaearon commented Oct 19, 2015

In my view this hurts predictability.
What is the use case compared to just firing one action instead of many?

@gaearon
Copy link
Contributor

gaearon commented Oct 19, 2015

Instead, the “Redux approach” to this would be to create a batching action creator:

function batchActions(...actions) {
  return {
    type: 'BATCH_ACTIONS',
    actions: actions
  };
}

// usage
store.dispatch(
  batchActions(
    doSomething(),
    doSomethingElse()
  )
);

and a higher order reducer:

function enableBatching(reducer) {
  return function batchingReducer(state, action) {
    switch (action.type) {
    case 'BATCH_ACTIONS':
      return action.actions.reduce(batchingReducer, state);
    default:
      return reducer(state, action);
    }
  }
}

// usage
let store = createStore(enableBatching(reducer));

@gaearon gaearon added the docs label Oct 19, 2015
@gaearon
Copy link
Contributor

gaearon commented Oct 19, 2015

We might want to add this to the docs..

@fubhy
Copy link

fubhy commented Oct 19, 2015

I solved this with a middleware that acts on action yielding generators.

@tshelburne
Copy link
Author

@gaearon I have a situation where I need to set a property (action creator 1), validate via external service the new value of the property (action creator 2), get the initial state via external service of another object based on that property, and then set that object in the state as well (action creator 3), and then finally validate the entirety of the new state via another external service (action creator 4). The place where things fell apart for me was the external service parts - if I allow subscribers to receive a notification after action 1, they receive an incoherent state, but I kept finding myself pushed to make the async calls in the reducers in order to move in the direction you described.

If I'm reading your suggestion right, I basically need to create a list of actions to run at the end of a promise chain that gets dispatched all at once. Rather than dispatching actions to the store to get updated state, I use getState initially and run my reducer manually against that "copy" to build the list of simple object actions that will ultimately be run in the store. Does this sound right?

This all felt a bit manual to me before, but I think that does pretty drastically improve the predictability of things.

@tshelburne
Copy link
Author

@gaearon That's a much better solution - thanks for the direction, feel free to close this.

@tshelburne
Copy link
Author

Also, note that the arguments in your higher order reducer for the passthrough are reversed - should be reducer(state, action)

@tshelburne
Copy link
Author

I also noticed that it's better to use batchingReducer recursively to enable combining batched actions into larger groups.

function enableBatching(reducer) {
  return function batchingReducer(state, action) {
    switch (action.type) {
    case 'BATCH_ACTIONS':
      return action.actions.reduce(batchingReducer, state);
    default:
      return reducer(state, action);
    }
  }
}

@gaearon
Copy link
Contributor

gaearon commented Oct 19, 2015

Good points. Want to publish this as a package?

@tshelburne
Copy link
Author

Will do - I'll take care of it tonight and ping you.

@tshelburne
Copy link
Author

Added to GH and published on npm - let me know your thoughts: https://github.com/tshelburne/redux-batched-actions

@gaearon
Copy link
Contributor

gaearon commented Oct 20, 2015

12661e5

@gaearon gaearon closed this as completed Oct 20, 2015
@gaearon gaearon changed the title Add 'redux-skip-by-action' to Ecosystem Batching actions Oct 27, 2015
This was referenced Oct 27, 2015
@vytenisu
Copy link

A bit late here, but one more independently created alternative for reducing notifications from Redux is https://www.npmjs.com/package/redux-notification-enhancer. Throttling and ability to disable actions in one package.

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

No branches or pull requests

4 participants