Skip to content

Instantly share code, notes, and snippets.

@Tahseenm
Last active January 1, 2018 15:25
Show Gist options
  • Save Tahseenm/935597a03bb15d6c7b8df4c009053f96 to your computer and use it in GitHub Desktop.
Save Tahseenm/935597a03bb15d6c7b8df4c009053f96 to your computer and use it in GitHub Desktop.
Minimal redux(y) lib
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
/**
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