簡單實現redux,瞭解redux原理

  1. 實現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
    } 
}
  1. 中間件實現

    核心就是按順序執行中間件函數, 接下來從最終使用開始倒推實現

    1. 使用:
    const store = createStore(counterReducer, applyMiddleware([ thunk, logger]))
    
    1. createStore 傳入enhancer

      //如果有中間件來加強 就走入中間件的邏輯
      if(enhancer) {
      	return enhancer(createStore)(reducer)
      }
      
    2. 實現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))))
      }
      
    3. 約定中間件: 所有的中間件都需要執行三次

      1. 第一次 傳入 dispatch, getState 供某些特殊中間件使用
      2. 第二次 傳入 dispatch 爲了鏈接其他中間件
      3. 第三次 傳入 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) 
          }
      }
      
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章