Last active
January 1, 2018 15:25
-
-
Save Tahseenm/935597a03bb15d6c7b8df4c009053f96 to your computer and use it in GitHub Desktop.
Minimal redux(y) lib
This file contains 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
import { createStore } from './lib' | |
/** | |
* Main reducer | |
*/ | |
const counter = function (state = 0, action) { | |
switch (action.type) { | |
case 'INCREMENT': | |
return state + 1 | |
case 'DECREMENT': | |
return state - 1 | |
default: | |
return state | |
} | |
} | |
/** | |
* App Store: api -> { subscribe, dispatch, getState } | |
*/ | |
const store = createStore(counter) | |
/** | |
* Update the UI in response to state changes or persist state to localStorage | |
*/ | |
store.subscribe(() => | |
console.log(store.getState()) | |
) | |
/** | |
* Mutate the State | |
*/ | |
store.dispatch({ type: 'INCREMENT' }); // 1 | |
store.dispatch({ type: 'INCREMENT' }); // 2 | |
store.dispatch({ type: 'DECREMENT' }); // 1 | |
store.dispatch({ type: 'DECREMENT' }); // 0 |
This file contains 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
/** | |
Simple createStore implementation | |
[1]. New state. | |
[2]. Notify the listeners of state change. | |
*/ | |
/* :: (Function, mixed) -> Object */ | |
const createStore = (reducer, preloadedState) => { | |
let currReducer = reducer | |
let currState = preloadedState | |
let listeners = [] | |
/* Function -> () -> void */ | |
const unsubscriber = listener => () => { | |
listeners = listeners.filter($listener => $listener !== listener) | |
} | |
const api = { | |
getState() { | |
return currState | |
}, | |
dispatch(action) { | |
currState = currReducer(currState, action) /* [1] */ | |
listeners.forEach(listener => listener()) /* [2] */ | |
}, | |
subscribe(newListener) { | |
listeners.push(newListener) | |
return unsubscriber(newListener) | |
}, | |
replaceReducer(nextReducer) { | |
currReducer = nextReducer | |
}, | |
} | |
return api | |
} | |
/* :: (Object, Object) -> (Object, Array<>) -> Object */ | |
const newState = (state, action) => (stateAccumulator, [key, reducer]) => | |
Object.assign(stateAccumulator, { | |
[key]: reducer(state[key], action) | |
}) | |
/* :: Object -> Reducer */ | |
const combineReducers = stateMap => (state, action) => | |
Object.entries(stateMap).reduce(newState(state, action), {}) | |
export default { | |
createStore, | |
combineReducers, | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment