- 實現createStore、getState、subscribe、dispatch
export function createStore(reducer, enhancer){
let currentState = undefined;
let currentListeners = [];
//提供getState方法
function getState(){
return currentState
}
//訂閱方法: 把訂閱函數 push到 數組中
function subscribe(listener){
currentListeners.push(listener)
}
//更新方法: 就是執行reducer 順便把訂閱方法都執行了
function dispatch(action){
currentState = reducer(currentState, action)
currentListeners.forEach(v=>v())
return action
}
// 第一次設置下默認值, 設置一個不太可能會寫在reducer裏面的值
dispatch({type:'@impossible/Type@'})
return {
getState,
subscribe,
dispatch
}
}
-
中間件實現
核心就是按順序執行中間件函數, 接下來從最終使用開始倒推實現
- 使用:
const store = createStore(counterReducer, applyMiddleware([ thunk, logger]))
-
createStore 傳入enhancer
//如果有中間件來加強 就走入中間件的邏輯 if(enhancer) { return enhancer(createStore)(reducer) }
-
實現applyMiddleware
export function applyMiddleware(middlewares) { return createStore => (...args) => { //第一步先創建好原來的store const store = createStore(...args) let dispatch = store.dispatch const midApi = { getState: store.getState, dispatch:(...args)=>dispatch(...args) } // 將所有的中間件執行一次 返回數組 dispatch => action =>{} const middlewareChain = middlewares.map(middleware => middleware(midApi)) // compose 將數組的 dispatch => action =>{} 轉換成一個 dispatch => action =>{} // 執行傳入 dispatch 得到新的dispatch dispatch = compose(middlewareChain)(store.dispatch) return { ...store, dispatch } } } function compose(funcs) { if(funcs.length == 1) { return funcs[0] } return funcs.reduce((left,right) => ((...args) => right(left(...args)))) }
-
約定中間件: 所有的中間件都需要執行三次
- 第一次 傳入 dispatch, getState 供某些特殊中間件使用
- 第二次 傳入 dispatch 爲了鏈接其他中間件
- 第三次 傳入 action, 真正執行中間件代碼, 使用第二次傳入的dispatch 按順序執行下一個中間件
function logger({dispatch, getState}) { return dispatch => action => { // 中間件任務 console.log(action.type + '執行了!!'); // 下一個中間件 return dispatch(action); } } function thunk({dispatch, getState}) { return dispatch => action => { if (typeof action == 'function') { return action(dispatch, getState) } return dispatch(action) } }