Redux store enhancer to allow batched dispatch.
yarn:
yarn add redux-batched-dispatch
npm:
npm install --save redux-batched-dispatch
import { createBatchEnhancer } from 'redux-batched-dispatch';
import { createStore } from 'redux';
const store = createStore(reducer, createBatchEnhancer());
// Batched dispatch will notify to listeners only once after store updated
store.dispatch([
{ type: 'Hello' },
{ type: 'World' },
]);
import { createBatchEnhancer } from 'redux-batched-dispatch';
import { createStore } from 'redux';
import throttle from 'lodash.throttle';
import debounce from 'lodash.debounce';
function reducer(state = [], action) {
switch (action.type) {
case 'PUSH':
return [...state, action.value];
default:
return state;
}
}
function push(value) {
return {
type: 'PUSH',
value,
};
}
const store = createStore(
reducer,
createBatchEnhancer({
// Invoke `dispatch`, but not more than once every 100ms.
'DISPATCH_THROTTLE': dispatch => throttle(dispatch, 100, { leading: false }),
// Invoke `dispatch`, debouncing 100ms
'DISPATCH_DEBOUNCE': dispatch => debounce(dispatch, 100),
}),
);
store.subscribe(() => {
console.log(store.getState());
});
setTimeout(() => { store.dispatch(push('T1'), 'DISPATCH_THROTTLE') }, 0);
setTimeout(() => { store.dispatch(push('T2'), 'DISPATCH_THROTTLE') }, 20);
setTimeout(() => { store.dispatch(push('T3'), 'DISPATCH_THROTTLE') }, 40);
setTimeout(() => { store.dispatch(push('T4'), 'DISPATCH_THROTTLE') }, 260);
setTimeout(() => { store.dispatch(push('D1'), 'DISPATCH_DEBOUNCE') }, 0);
setTimeout(() => { store.dispatch(push('D2'), 'DISPATCH_DEBOUNCE') }, 70);
setTimeout(() => { store.dispatch(push('D3'), 'DISPATCH_DEBOUNCE') }, 140);
setTimeout(() => { store.dispatch(push('D4'), 'DISPATCH_DEBOUNCE') }, 300);
// stdout1:100ms => ['T1', 'T2', 'T3']
// stdout2:240ms => ['T1', 'T2', 'T3', 'D1', 'D2', 'D3']
// stdout3:360ms => ['T1', 'T2', 'T3', 'D1', 'D2', 'D3', 'T4']
// stdout4:400ms => ['T1', 'T2', 'T3', 'D1', 'D2', 'D3', 'T4', 'D4']
You can use extra middlewares like redux-thunk, redux-saga, redux-observable, etc..
import { createBatchEnhancer } from 'redux-batched-dispatch';
import { createStore, applyMiddleware } from 'redux';
const store = createStore(
reducer,
createBatchEnhancer(
applyMiddleware(exampleMiddleware),
{
'DISPATCH_DEBOUNCE': dispatch => debounce(dispatch, 100),
},
)
);
import { createBatchEnhancer } from 'redux-batched-dispatch';
const { createBatchEnhancer } = require('redux-batched-dispatch');
Add below <script>
tag to the HTML page right before the closing </body>
tag
<script src="https://unpkg.com/redux-batched-dispatch@1/dist/index.js" crossorigin></script>
And use global reduxBatchedDispatch
variable
batchAction(action, dispatchType)
You can also use batched dispatch with batchAction
action (Array | Object): The redux action
dispatchType (string): The type of dispatch defined when use createBatchEnhancer
import { batchAction } from 'redux-batched-dispatch';
dispatch(batchAction([
{ type: 'Hello' },
{ type: 'World' },
], 'DISPATCH_THROTTLE'));
It is useful on middleware(ex: redux-saga)
function* createTodo() {
yield put(batchAction([
{ type: 'Hello' },
{ type: 'World' },
], 'DISPATCH_THROTTLE'));
}
store.getActionQueue(dispatchType)
Get queue which contains actions from dispatch. This queue's reference will never change
dispatchType (string): The type of dispatch defined when use createBatchEnhancer
const store = createStore(
reducer,
createBatchEnhancer({
'DISPATCH_DEBOUNCE': dispatch => debounce(dispatch, 100),
})
);
const throttleQueue = store.getActionQueue('DISPATCH_DEBOUNCE');
const throttleQueue = store.getActionQueue('DISPATCH_DEBOUNCE');
// Clear all actions
throttleQueue.length = 0;
// Remove last action
throttleQueue.pop();
// Remove second action
throttleQueue.splice(1, 1);
import { createBatchEnhancer } from 'redux-batched-dispatch';
import { createStore } from 'redux';
import throttle from 'lodash.throttle';
let throttledDispatch;
const store = createStore(
reducer,
createBatchEnhancer({
'DISPATCH_THROTTLE': dispatch => {
throttledDispatch = throttle(dispatch, 100);
return throttledDispatch;
}
}),
);
$(window).on('popstate', throttledDispatch.cancel);
Even if cancel the throttledDispatch
, there are still actions in queue
If want to clear the queue, see the section Cancel actions in the queue