Created
March 29, 2017 13:15
-
-
Save nodew/b12c9e425c13da5127d1e7f21b607393 to your computer and use it in GitHub Desktop.
a simple redux, just has `createStore` and `combineReducer` method
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
/* | |
* demo reducer | |
* function demoReducer(state, action) { | |
* do something | |
* return state; | |
* } | |
* | |
* demo action | |
* { | |
* type: [type symbol] | |
* ... | |
* } | |
* */ | |
function createStore(reducer, preloadState) { | |
let currentState = preloadState | |
const actionTypes = { | |
INIT: Symbol() | |
} | |
function dispatch(action) { | |
if (typeof action !== 'object') { | |
throw new Error('action should be an object') | |
} | |
if(action.type === undefined) { | |
throw new Error('action type is undefined') | |
} | |
currentState = reducer(currentState, action) | |
} | |
function getState() { | |
return currentState | |
} | |
dispatch({ type: actionTypes.INIT }) | |
return { | |
getState, | |
dispatch | |
} | |
} | |
function combineReducer(reducers) { | |
const reducerKeys = Object.keys(reducers) | |
const finalReducers = {} | |
/* | |
* filter reducer isn't function | |
* */ | |
for (let i = 0; i < reducerKeys.length; i++) { | |
const key = reducerKeys[i] | |
if (typeof reducers[key] === 'function') { | |
finalReducers[key] = reducers[key] | |
} | |
} | |
const finalReducerKeys = Object.keys(finalReducers) | |
return function combination(state = {}, action) { | |
const nextState = {} | |
let hasChanged = false | |
for (let i = 0; i< finalReducerKeys.length; i++) { | |
const key = finalReducerKeys[i] | |
const reducer = finalReducers[key] | |
const previousStateForKey = state[key] | |
const nextStateForKey = reducer(previousStateForKey, action) | |
nextState[key] = nextStateForKey | |
hasChanged = hasChanged || nextStateForKey !== previousStateForKey | |
} | |
return hasChanged ? nextState : state | |
} | |
} | |
// ------------------------ test -------------------------- | |
const actionTypes = { | |
add: Symbol(), | |
minus: Symbol(), | |
updateA: Symbol(), | |
updateB: Symbol() | |
} | |
const reducer = (state, action) => { | |
switch (action.type) { | |
case actionTypes.add: | |
return state + action.value | |
case actionTypes.minus: | |
return state - action.value | |
default: | |
return state | |
} | |
} | |
var store = createStore(reducer, 0) | |
console.log(store.getState()) | |
store.dispatch({ | |
type: actionTypes.add, | |
value: 3 | |
}) | |
console.log(store.getState()) | |
store.dispatch({ | |
type: actionTypes.minus, | |
value: 1 | |
}) | |
console.log(store.getState()) | |
// ------------------- test combine reducer -------------------- | |
const stateA = (state = 0, action) => { | |
switch(action.type) { | |
case actionTypes.updateA: | |
return action.value | |
default: | |
return state | |
} | |
} | |
const stateB = (state = 2, action) => { | |
switch(action.type) { | |
case actionTypes.updateB: | |
return action.value | |
default: | |
return state | |
} | |
} | |
const reducers = combineReducer({ | |
stateA, | |
stateB | |
}) | |
const storeB = createStore(reducers) | |
console.log(storeB.getState()) | |
storeB.dispatch({ | |
type: actionTypes.updateA, | |
value: 21 | |
}) | |
storeB.dispatch({ | |
type: actionTypes.updateB, | |
value: 12 | |
}) | |
console.log(storeB.getState()) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment