Skip to content

Instantly share code, notes, and snippets.

@vladanyes
Created January 24, 2021 14:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save vladanyes/7e046b522db2c678a41cc81330685aee to your computer and use it in GitHub Desktop.
Save vladanyes/7e046b522db2c678a41cc81330685aee to your computer and use it in GitHub Desktop.
Simple Redux
const INC = 'increment';
const DEC = 'decrement';
const RES = 'reset';
const ADD = 'add';
function createStore(rootReducer, initialStore) {
let store = initialStore;
let subscribers = [];
return {
getState: () => store,
dispatch: (action) => {
store = rootReducer(store, action);
subscribers.forEach(sub => sub());
},
subscribe: (callback) => {
subscribers.push(callback);
return () => {
subscribers = subscribers.filter(sub => sub !== callback);
};
},
}
};
function increment() {
return {
type: INC,
payload: 1,
}
}
function decrement() {
return {
type: DEC,
payload: 1,
}
}
function reset() {
return {
type: RES,
}
}
function add(payload) {
return {
type: ADD,
payload,
}
}
function reducerNumber(store, action) {
if (action.type === INC) {
return store + action.payload;
}
if (action.type === DEC) {
return store - action.payload;
}
return store;
}
function reducerString(store, action) {
if (action.type === ADD) {
return store + action.payload;
}
if (action.type === RES) {
return '';
}
return store;
}
function combineReducers(reducersObj) {
const reducerKeys = Object.keys(reducersObj);
return function combine(state, action) {
let nextState = state;
reducerKeys.forEach(key => {
const reducer = reducersObj[key]
const previousStateForKey = state[key]
const nextStateForKey = reducer(previousStateForKey, action)
nextState[key] = nextStateForKey;
});
return nextState;
}
}
const initialStore = {
number: 0,
string: 'zero',
};
const reducers = {
number: reducerNumber,
string: reducerString,
};
function applyMiddleware(...middlewares) {
return (createStore) => (reducer, preloadedState, enhancer) => {
const store = createStore(reducer, preloadedState, enhancer)
let dispatch = store.dispatch
let chain = []
const middlewareAPI = {
getState: store.getState,
dispatch: (action) => dispatch(action)
}
chain = middlewares.map(middleware => middleware(middlewareAPI))
dispatch = compose(...chain)(store.dispatch)
return {
...store,
dispatch
}
}
}
function compose(...funcs) {
if (funcs.length === 0) {
return arg => arg
}
if (funcs.length === 1) {
return funcs[0]
}
const last = funcs[funcs.length - 1]
const rest = funcs.slice(0, -1)
return (...args) => rest.reduceRight((composed, f) => f(composed), last(...args))
}
const store = createStore(combineReducers(reducers), initialStore);
window.store = store;
store.subscribe(() => {
console.log('Current store is: ', store.getState())
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment