Skip to content

Instantly share code, notes, and snippets.

@dews
Forked from gaearon/slim-redux.js
Last active March 7, 2021 14:03
Show Gist options
  • Save dews/3f3719fd2b1ef45904856c70badcbfa1 to your computer and use it in GitHub Desktop.
Save dews/3f3719fd2b1ef45904856c70badcbfa1 to your computer and use it in GitHub Desktop.
Add applyMiddleware and add example
function mapValues(obj, fn) {
return Object.keys(obj).reduce((result, key) => {
result[key] = fn(obj[key], key);
return result;
}, {});
}
function pick(obj, fn) {
return Object.keys(obj).reduce((result, key) => {
if (fn(obj[key])) {
result[key] = obj[key];
}
return result;
}, {});
}
function bindActionCreator(actionCreator, dispatch) {
return (...args) => dispatch(actionCreator(...args));
}
function bindActionCreators(actionCreators, dispatch) {
return typeof actionCreators === "function"
? bindActionCreator(actionCreators, dispatch)
: mapValues(actionCreators, actionCreator =>
bindActionCreator(actionCreator, dispatch)
);
}
function compose(...funcs) {
return arg => {
return funcs.reduceRight((composed, f) => {
return f(composed);
}, arg);
};
}
function applyMiddleware(...middlewares) {
return next => (reducer, initialState) => {
var store = next(reducer, initialState);
var dispatch = store.dispatch;
var chain = [];
chain = middlewares.map(middleware =>
middleware({
getState: store.getState,
dispatch: action => dispatch(action)
})
);
preDispatch = compose(...chain);
dispatch = preDispatch(store.dispatch);
return {
...store,
dispatch
};
};
}
function combineReducers(reducers) {
var finalReducers = pick(reducers, val => typeof val === "function");
return (state = {}, action) =>
mapValues(finalReducers, (reducer, key) => reducer(state[key], action));
}
function createStore(reducer, initialState, enhancer) {
if (typeof enhancer !== "undefined") {
if (typeof enhancer !== "function") {
throw new Error("Expected the enhancer to be a function.");
}
return enhancer(createStore)(reducer, initialState);
}
var currentReducer = reducer;
var currentState = initialState;
var listeners = [];
var isDispatching = false;
function getState() {
return currentState;
}
function subscribe(listener) {
listeners.push(listener);
return function unsubscribe() {
var index = listeners.indexOf(listener);
listeners.splice(index, 1);
};
}
function dispatch(action) {
if (isDispatching) {
throw new Error("Reducers may not dispatch actions.");
}
try {
isDispatching = true;
currentState = currentReducer(currentState, action);
} finally {
isDispatching = false;
}
listeners.slice().forEach(listener => listener());
return action;
}
function replaceReducer(nextReducer) {
currentReducer = nextReducer;
dispatch({
type: "@@redux/INIT"
});
}
dispatch({
type: "@@redux/INIT"
});
return {
dispatch,
subscribe,
getState,
replaceReducer
};
}
/**
* Example
*
*/
function counter(state = 0, action) {
switch (action.type) {
case "INCREMENT":
return state + 1;
case "DECREMENT":
return state - 1;
default:
return state;
}
}
let logger = store => next => action => {
console.log("dispatching", action);
let result = next(action);
console.log("next state", store.getState());
return result;
};
let logger2 = store => next => action => {
console.log("dispatching2", action);
let result = next(action);
console.log("next state2", store.getState());
return result;
};
let store = createStore(counter, 0, applyMiddleware(logger, logger2));
store.subscribe(() => console.log("subscribe", store.getState()));
@dews
Copy link
Author

dews commented Apr 5, 2020

Run it,

# store.dispatch({ type: 'INCREMENT' })

Result,

dispatching {type: "INCREMENT"}
dispatching2 {type: "INCREMENT"}
subscribe 1
next state2 1
next state 1
{type: "INCREMENT"}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment