redux-batched-subscribe
redux-batched-subscribe copied to clipboard
Example: Selective batching based on meta.batch in Action
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 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?
I'm happy if @tappleby would like to do that.