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

Example: Selective batching based on meta.batch in Action #24

Open
davidjbradshaw opened this issue Feb 5, 2018 · 2 comments
Open

Example: Selective batching based on meta.batch in Action #24

davidjbradshaw opened this issue Feb 5, 2018 · 2 comments

Comments

@davidjbradshaw
Copy link

davidjbradshaw commented Feb 5, 2018

Following on from the examples of @staab and @peteruithoven. Here is an example that selectively batches actions using requestAnimationFrame, based on the presence of meta.batch in an action. It uses a middleware to inspect actions and call notify().

This allows the batching, for example async actions, whilst letting everything else work as normal.

You can replace rafUpdateBatcher() with LoDash's debounce() if you prefer.

batching/state.js

export default {
  notify: null
}

batching/enhancer.js

import { batchedSubscribe } from 'redux-batched-subscribe'
import State from './state'

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

batching/rafUpdateBatcher.js

import raf from 'raf'
import State from './state'

let rafID

function delayedNotify () {
  rafID = null
  State.notify()
}

export default function rafUpdateBatcher () {
  if (rafID) return // prevent multiple request animation frame callbacks
  rafID = raf(delayedNotify)
}

batching/middleware.js

import rafUpdateBatcher from 'rafUpdateBatcher'
import State from './state'

const shouldBatch = action => action.meta && action.meta.batch

export default () => next => (action) => {
  const resolved = next(action)

  if (State.notify && !shouldBatch(action)) {
    State.notify()
  } else {
    rafUpdateBatcher()
  }

  return resolved
}

store.js

import { applyMiddleware, compose, createStore } from 'redux'
import batchedSubscribeMiddleware from './batching/middleware'
import batchedSubscribeEnhancer from './batching/enhancer'

const store = createStore(
  reducer,
  intialState,
  compose(
    batchedSubscribeEnhancer,
    applyMiddleware(batchedSubscribeMiddleware)
  )
)

Example action

{
   type: ACTION,
   payload: { ... },
   meta: { batch: true }
}
@davidjbradshaw davidjbradshaw changed the title Example: Selective batching based on meta.batch Example: Selective batching based on meta.batch in Action Feb 12, 2018
@Mamoru1234
Copy link

@davidjbradshaw Thank you for your example it was extremely useful to me.
Maybe it makes sense to post somewhere(for example on wiki) and refer it in REAME, what do you think?

@davidjbradshaw
Copy link
Author

I'm happy if @tappleby would like to do that.

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

No branches or pull requests

2 participants