|
/// createStore |
|
function createStore(reducer, initialState, enhancer) { |
|
if (typeof initialState === 'function') { |
|
enhancer = initialState; |
|
initialState = undefined; |
|
} |
|
if (typeof enhancer === 'function') { |
|
return enhancer(createStore)(reducer, initialState); |
|
} |
|
|
|
let state = initialState; |
|
|
|
return { |
|
dispatch: (action) => { |
|
state = reducer(state, action); |
|
}, |
|
getState: () => state, |
|
}; |
|
} |
|
/// applyMiddleware |
|
function applyMiddleware(...middlewares) { |
|
return (createStore) => (reducer, initialState) => { |
|
const store = createStore(reducer, initialState); |
|
const middlewareAPI = { |
|
getState: store.getState, |
|
dispatch: (action) => dispatch(action), |
|
}; |
|
|
|
const chain = middlewares.map((middleware) => middleware(middlewareAPI)); |
|
const dispatch = compose(...chain)(store.dispatch); |
|
return { |
|
...store, |
|
dispatch, |
|
}; |
|
}; |
|
} |
|
/// compose |
|
function compose(...functions) { |
|
return functions.reduce( |
|
(acc, val) => |
|
(...args) => |
|
acc(val(...args)) |
|
); |
|
} |
|
/// custom reducer if alone |
|
function standaloneReducer(state = { value: 0 }, action) { |
|
switch (action.type) { |
|
case 'INCREMENT': |
|
return { ...state, value: state.value + 1 }; |
|
case 'DECREMENT': |
|
return { ...state, value: state.value - 1 }; |
|
default: |
|
return state; |
|
} |
|
} |
|
/// compostition global |
|
function globalReducer(state = {}, action) { |
|
return { |
|
value: reducer(state.value, action), |
|
}; |
|
} |
|
/// custom reducer |
|
function reducer(state = 0, action) { |
|
switch (action.type) { |
|
case 'INCREMENT': |
|
return state + 1; |
|
case 'DECREMENT': |
|
return state - 1; |
|
default: |
|
return state; |
|
} |
|
} |
|
/// custom middleware |
|
function helloLog(store) { |
|
return (next) => (action) => { |
|
console.log('hello'); |
|
next(action); |
|
}; |
|
} |
|
|
|
/// creation of store |
|
var store = createStore(globalReducer, applyMiddleware(helloLog)); |
|
/// dispatching |
|
store.dispatch({ type: 'INCREMENT' }); |
|
/// looking at result |
|
store.getState(); /// {value: 1} |