redux-batched-subscribe icon indicating copy to clipboard operation
redux-batched-subscribe copied to clipboard

Example: Selective batching based on meta.batch in Action

Open davidjbradshaw opened this issue 7 years ago • 2 comments

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 avatar Feb 05 '18 10:02 davidjbradshaw

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

Mamoru1234 avatar Aug 13 '18 09:08 Mamoru1234

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

davidjbradshaw avatar Aug 13 '18 11:08 davidjbradshaw