­

自己簡寫一個redux(redux源碼簡寫)

  • 2020 年 2 月 14 日
  • 筆記

 直接看程式碼

mydux.js文件  function createStore(reducer) {      /**       * 1.註冊用到的方法,並return出去提供使用       * 2.定義默認的狀態與事件池       * 3.默認先觸發一次dispatch給state賦予默認值       * 4.componentDidMount後會通過subscribe往狀態池中追加事件       * 5.在具體的事件處觸發dispatch,傳入具體的action,修改state的值,並且觸發事件池中的事件,從而更新組件       */      let state,          listeners = [];      function dispatch(action) {          //傳入state和action,返回修改後最新的state狀態值          state = reducer(state, action);          //通知事件事件池中的方法執行          for (let i = 0; i<listeners.length; i++){              let curFn = listeners[i];              if (typeof curFn === 'function') {                  curFn();                  continue;              }              //不是函數的移除掉              listeners[i].splice(i, 1);              i--;          }      }      //組件通過getState獲取最新的狀態值(此處要深拷貝一下,避免組件直接通過對象引用修改狀態值,redux的源碼中貌似沒有深拷貝,存在一些缺陷)      function getState() {          return JSON.parse(JSON.stringify(state));      }      function subscribe(fn) {          //此處進行一個去重複,避免添加重複的事件(redux的源碼中貌似也沒有去重複,存在一些缺陷)          for (let i = 0; i<listeners.length; i++){              if (listeners[i] === fn) {                  return;              }          }          listeners.push(fn);          //返回一個移除事件的函數,可以進行調用,從事件池中移除追加的事件          return function unsubscribe () {              let index = listeners.indexOf(fn);              if (index > -1) {                  // listeners.splice(index, 1);  //這個地方不能用splice,可能會導致數組塌陷問題                  listeners[index] = null;              }          };      }      //創建的時候先調用一下,為了是當默認state沒值的時候,觸發reducer給初始化的state賦予一個默認值      dispatch({          type: `@@redux/INIT${Math.random()}`      });      return {          dispatch,          getState,          subscribe      }  }  export {      createStore  }
App.js文件  import {createStore} from './redux/mydux.js'    let store = createStore(reducer);  window.store = store;    function reducer(state = {      n: 0,      m: 0  }, action) {      //reducer就是根據不同的行為標識來修改狀態資訊的      switch (action.type) {          case 'support': state.n = state.n+1;break;          case 'against': state.m = state.m+1;break;      }      return state;   //return的是什麼,就會把store中的狀態改成什麼  }