Created
August 8, 2016 00:43
-
-
Save miyucy/6bd90005a407a531efd47dc376961f65 to your computer and use it in GitHub Desktop.
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
const actionCreator = () => ({ type: 'SOME_ACTION' }); | |
const noopReducer = (state, action) => state; | |
const noopEnhancer = (store) => store; | |
const noopMiddleware = store => next => action => next(action); | |
export function createStore(reducer = noopReducer, initialState = undefined, enhancer = noopEnhancer) { | |
let state = initialState; | |
let listeners = []; | |
const dispatch = (action) => { | |
state = reducer(state, action); | |
listeners.forEach((f) => f()); | |
return action; | |
}; | |
return enhancer({ | |
dispatch, | |
getState: () => state, | |
subscribe: (listener) => listeners.push(listener), | |
unsubscribe: () => listeners = [], | |
}); | |
} | |
export function applyMiddleware(...middlewares) { | |
return (store) => { | |
let dispatch = store.dispatch; | |
middlewares.reverse(); | |
middlewares.forEach((middleware) => { | |
dispatch = middleware(store)(dispatch); | |
}); | |
return Object.assign({}, store, { dispatch }); | |
}; | |
} | |
export function combineReducers(reducers) { | |
return function (state, action) { | |
return Object.keys(reducers).reduce((newState, key) => { | |
const reducer = reducers[key]; | |
return Object.assign({}, newState, { | |
[key]: reducer(state[key], action) | |
}); | |
}, {}); | |
}; | |
} | |
export function bindActionCreators(actionCreators, dispatch) { | |
return Object.keys(actionCreators).reduce((newActionCreators, key) => { | |
const actionCreator = actionCreators[key]; | |
return Object.assign({}, newActionCreators, { | |
[key]: (...args) => { | |
const action = actionCreator(...args); | |
dispatch(action); | |
} | |
}); | |
}, {}); | |
} |
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 assert from 'assert'; | |
import { | |
createStore, combineReducers, bindActionCreators, applyMiddleware | |
} from './redux'; | |
describe('redux', () => { | |
describe('createStore', () => { | |
const reducer = (state = 0, action) => { | |
switch (action.type) { | |
case 'incr': | |
return state + 1; | |
case 'decr': | |
return state - 1; | |
case 'Incr': | |
return state + action.n; | |
case 'Decr': | |
return state - action.n; | |
default: | |
return state; | |
}; | |
}; | |
const logger1 = store => next => action => { | |
console.log('[1] before', action); | |
const result = next(action); | |
console.log('[1] after', store.getState()); | |
return result; | |
}; | |
const logger2 = store => next => action => { | |
console.log('[2] before', action); | |
const result = next(action); | |
console.log('[2] after', store.getState()); | |
return result; | |
}; | |
it('', () => { | |
const store = createStore(reducer, 0); | |
store.subscribe(() => console.log('listener', store.getState())); | |
store.dispatch({ type: 'incr' }); | |
store.dispatch({ type: 'decr' }); | |
store.unsubscribe(); | |
}); | |
it('', () => { | |
const store = createStore(reducer, 0, applyMiddleware(logger1, logger2)); | |
store.dispatch({ type: 'Incr', n: 100 }); | |
store.dispatch({ type: 'Decr', n: -50 }); | |
}); | |
}); | |
describe('combineReducers', () => { | |
const incr = (state = 0, action) => state + 1; | |
const decr = (state = 0, action) => state - 1; | |
it('', () => { | |
const reducer = combineReducers({ incr, decr }); | |
const state = reducer({ incr: 0, decr: 1 }, { type: 'noop' }); | |
assert(state.incr === 1); | |
assert(state.decr === 0); | |
}); | |
}); | |
describe('bindActionCreators', () => { | |
const seq = (a, b, c) => { | |
return { type: 'action', a, b, c }; | |
}; | |
const inv = (a, b, c) => { | |
return { type: 'action', x: a, y: b, z: c }; | |
}; | |
const dispatch = (action) => { | |
console.log(action); | |
}; | |
it('', () => { | |
const bounds = bindActionCreators({ seq, inv }, dispatch); | |
console.log('seq'); | |
seq(1, 2, 3); | |
console.log('bounds.seq'); | |
bounds.seq(1, 2, 3); | |
console.log('inv'); | |
inv(1, 2, 3); | |
console.log('bounds.inv'); | |
bounds.inv(1, 2, 3); | |
}); | |
}); | |
}); |
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
export default (store) => { | |
return (next) => { | |
return (action) => { | |
return ( | |
typeof action === 'function' ? | |
action(store.dispatch, store.getState) | |
: | |
next(action) | |
); | |
}; | |
}; | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment