Last active
December 28, 2021 09:23
-
-
Save markerikson/0383775096f2b32e48ad41499cf8a1fb to your computer and use it in GitHub Desktop.
Redux array batched actions enhancer
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// copy-pasta'd from isarray | |
var toString = {}.toString; | |
const isArray = Array.isArray || function (arr) { | |
return toString.call(arr) == '[object Array]'; | |
}; | |
export function batchedSubscribe() { | |
let currentListeners = []; | |
let nextListeners = currentListeners; | |
function ensureCanMutateNextListeners() { | |
if (nextListeners === currentListeners) { | |
nextListeners = currentListeners.slice(); | |
} | |
} | |
function subscribe(listener) { | |
if (typeof listener !== 'function') { | |
throw new Error('Expected listener to be a function.'); | |
} | |
let isSubscribed = true; | |
ensureCanMutateNextListeners(); | |
nextListeners.push(listener); | |
return function unsubscribe() { | |
if (!isSubscribed) { | |
return; | |
} | |
isSubscribed = false; | |
ensureCanMutateNextListeners(); | |
const index = nextListeners.indexOf(listener); | |
nextListeners.splice(index, 1); | |
}; | |
} | |
function notifyListeners() { | |
const listeners = currentListeners = nextListeners; | |
for (let i = 0; i < listeners.length; i++) { | |
listeners[i](); | |
} | |
} | |
return next => (...args) => { | |
const store = next(...args); | |
const subscribeImmediate = store.subscribe; | |
function dispatch(action) { | |
const actionIsArray = isArray(action); | |
const result = actionIsArray ? action.map(store.dispatch) : store.dispatch(action); | |
notifyListeners(); | |
return result; | |
} | |
return { | |
...store, | |
dispatch, | |
subscribe, | |
subscribeImmediate | |
}; | |
}; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html> | |
<head> | |
<title>Redux basic example</title> | |
<script src="https://npmcdn.com/redux@latest/dist/redux.min.js"></script> | |
<script src="reduxThunk.js"></script> | |
<script src="reduxBatchedDispatch.js"></script> | |
</head> | |
<body> | |
<div> | |
<p> | |
Clicked: <span id="value">0</span> times | |
<button id="increment">+</button> | |
<button id="decrement">-</button> | |
<button id="doubleIncrement">Double Increment</button> | |
<button id="doubleIncrementThunk">Double Increment (thunk)</button> | |
<button id="incrementIfOdd">Increment if odd</button> | |
<button id="incrementAsync">Increment async</button> | |
</p> | |
</div> | |
<script> | |
function counter(state, action) { | |
if (typeof state === 'undefined') { | |
return 0 | |
} | |
switch (action.type) { | |
case 'INCREMENT': | |
return state + 1 | |
case 'DECREMENT': | |
return state - 1 | |
default: | |
return state | |
} | |
} | |
var thunkMiddleware = createThunkMiddleware(); | |
var batchedSubscribeEnhancer = batchedSubscribe(); | |
var middlewareEnhancer = Redux.applyMiddleware(thunkMiddleware); | |
var composedEnhancers = Redux.compose(middlewareEnhancer, batchedSubscribeEnhancer); | |
var store = Redux.createStore(counter, undefined, composedEnhancers) | |
var valueEl = document.getElementById('value') | |
function render() { | |
valueEl.innerHTML = store.getState().toString() | |
} | |
render() | |
store.subscribe(render) | |
var notificationCounter = 0; | |
store.subscribe(function() { | |
notificationCounter += 1; | |
console.log("Notifications: ", notificationCounter); | |
}); | |
document.getElementById('increment') | |
.addEventListener('click', function () { | |
store.dispatch({ type: 'INCREMENT' }) | |
}) | |
document.getElementById('decrement') | |
.addEventListener('click', function () { | |
store.dispatch({ type: 'DECREMENT' }) | |
}) | |
document.getElementById('doubleIncrement') | |
.addEventListener('click', function () { | |
store.dispatch([ | |
{ type: 'INCREMENT' }, | |
{ type: 'INCREMENT' } | |
]) | |
}) | |
document.getElementById('doubleIncrementThunk') | |
.addEventListener('click', function () { | |
var thunk = function(dispatch, getState) { | |
dispatch([ | |
{ type: 'INCREMENT' }, | |
{ type: 'INCREMENT' } | |
]) | |
} | |
store.dispatch(thunk); | |
}) | |
document.getElementById('incrementIfOdd') | |
.addEventListener('click', function () { | |
if (store.getState() % 2 !== 0) { | |
store.dispatch({ type: 'INCREMENT' }) | |
} | |
}) | |
document.getElementById('incrementAsync') | |
.addEventListener('click', function () { | |
setTimeout(function () { | |
store.dispatch({ type: 'INCREMENT' }) | |
}, 1000) | |
}) | |
</script> | |
</body> | |
</html> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use strict'; | |
/* | |
exports = exports || {}; | |
Object.defineProperty(exports, "__esModule", { | |
value: true | |
}); | |
*/ | |
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; | |
//exports.batchedSubscribe = batchedSubscribe; | |
// copy-pasta'd from isarray | |
var toString = {}.toString; | |
var isArray = Array.isArray || function (arr) { | |
return toString.call(arr) == '[object Array]'; | |
}; | |
function batchedSubscribe() { | |
var currentListeners = []; | |
var nextListeners = currentListeners; | |
function ensureCanMutateNextListeners() { | |
if (nextListeners === currentListeners) { | |
nextListeners = currentListeners.slice(); | |
} | |
} | |
function subscribe(listener) { | |
if (typeof listener !== 'function') { | |
throw new Error('Expected listener to be a function.'); | |
} | |
var isSubscribed = true; | |
ensureCanMutateNextListeners(); | |
nextListeners.push(listener); | |
return function unsubscribe() { | |
if (!isSubscribed) { | |
return; | |
} | |
isSubscribed = false; | |
ensureCanMutateNextListeners(); | |
var index = nextListeners.indexOf(listener); | |
nextListeners.splice(index, 1); | |
}; | |
} | |
function notifyListeners() { | |
var listeners = currentListeners = nextListeners; | |
for (var i = 0; i < listeners.length; i++) { | |
listeners[i](); | |
} | |
} | |
return function (next) { | |
return function () { | |
var store = next.apply(undefined, arguments); | |
var subscribeImmediate = store.subscribe; | |
function dispatch(action) { | |
var actionIsArray = isArray(action); | |
var result = actionIsArray ? action.map(store.dispatch) : store.dispatch(action); | |
notifyListeners(); | |
return result; | |
} | |
return _extends({}, store, { | |
dispatch: dispatch, | |
subscribe: subscribe, | |
subscribeImmediate: subscribeImmediate | |
}); | |
}; | |
}; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function createThunkMiddleware(extraArgument) { | |
return function (_ref) { | |
var dispatch = _ref.dispatch; | |
var getState = _ref.getState; | |
return function (next) { | |
return function (action) { | |
if (typeof action === 'function') { | |
return action(dispatch, getState, extraArgument); | |
} | |
return next(action); | |
}; | |
}; | |
}; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment