tappleby / redux-batched-subscribe

store enhancer for https://github.com/reactjs/redux which allows batching subscribe notifications.
MIT License
504 stars 32 forks source link

Pass through dispatch action to batch function #13

Open ryardley opened 8 years ago

ryardley commented 8 years ago

Having the action available at the batching function level is important for calculating batch exclusion based on action type. This is important for things like transactional batching triggered by specific actions which is a use case we came across.

ryardley commented 8 years ago

I just saw a second PR from January un-merged that does exactly the same thing. Are there any issues with this?

tappleby commented 7 years ago

Looking into getting this PR merged soon. Just evaluating the impact future redux store enhancer api changes might have on this:

sagar-sm commented 7 years ago

I was just about to implement this exact same functionality when I came across this PR. @tappleby Is there an ETA on merging this? https://github.com/reactjs/redux/pull/1702 and https://github.com/reactjs/redux/pull/2214#discussion_r98359849 are still in review but seem to be stale since January.

paynecodes commented 6 years ago

@tappleby Any updates here?

I understand that this is something that the Redux team isn't offering positive feedback in this direction based on the linked issues, but I'm struggling to see how this lib can be used without receiving the action (controlled components). Am I missing something?

staab commented 6 years ago

I also started implementing this same functionality, then I forked @sagar-sm's version - but then I realized that this stuff is pretty easy to compose to get whatever behavior you need (in my case, at the expense of some global mutable variables - but not terribly hacky, you could easily encapsulate them if you wanted). Here's what I did:

batching/state.js

export default {notify: null, paused: false}

batching/enhancer.js

import {batchedSubscribe} from 'redux-batched-subscribe'
import State from 'modules/batch-actions/state'

export default batchedSubscribe(freshNotify => {
  State.notify = freshNotify
})

batching/middleware.js

import State from 'modules/batch-actions/state'

export default store => next => action => {
  if (action.type === 'PAUSE_SUBS') {
    State.paused = true
  }

  if (action.type === 'RESUME_SUBS') {
    State.paused = false
  }

  next(action)

  // Wait all actions has been applied to the store to notify
  if (!State.paused) {
    State.notify()
  }
}

Once you stick the middleware and the enhancer in the right place, you can imperatively persist store changes to your components, e.g.:

dispatch({type: 'PAUSE_SUBS'})
dispatch({type: 'LEAVES_STORE_IN_INCONSISTENT_STATE'})
dispatch({type: 'FIXES_INCONSISTENT_STATE'})
dispatch({type: 'RESUME_SUBS'})

This suited my needs just fine, but isn't really ideal since the store's state should probably be in a consistent state at all times, but unfortunately we didn't develop the right abstractions to do that for our app until it was too late and a refactor had become expensive.

Hopefully this helps someone else out (I noticed sagar-sm's fork has 22 forks of its own) - and of course, my implementation is only like 20 lines, so you could do something very different in the middleware to suit your needs.