讀redux有感: redux原來是這樣操做的。

2017.9.10日 教師節 : ~當一個事物你沒有接觸,可是生活中 經常用到他,你就不得不去了解他了。redux

1. redux的基本原理

redux就是對一個倉庫(store)的操做,咱們能夠佈置好多倉位(state)(如: 水果、零食、糕點)等,他們每個倉位(state)存儲着不一樣的物品,每個倉位都有一個操做系統(reducer), 這個操做系統能夠進行入庫物品(ADD)、統計件數(COUNT)、篩選好(FILTER_GOOD)/壞(FILTER_BAD)等操做,這些操做都用一個統一的標籤(type)來表示。好了比喻就到這裏。數組

redux規定:閉包

1. 用戶每一次操做store都要觸發一個action,這個action僅僅是告訴redux:1. 我要操做的類型type,2. 我提供的數據。觸發條件dispatch({type: ... , data: ...});函數

function addTodo(content) {
  return {
    type: ADD_TODO,
    content: content
  }
}

dispatch(addTodo('你好啊'))

如上代碼,咱們觸發了一個行爲ADD_TODO工具

2. 觸發一個行爲後,真正的state操做在reducer裏完成,reducer裏要作的事: 1. 任何狀況都要返回一個state,2. 根據不一樣的type作不一樣的操做spa

function todoApp(state=[], action) {
  switch(action.type) {
    case ADD_TODO:
    return [
      ...state,
      {
        content: action.content,
        completed: false
      }
    ],
    case REMOVE_TODO:
    return [
        ...state.filter(item => item.id != action.id)
    ]
    default: 
    return state
  }
}    

差很少就像上面這樣,定義了一個reducer函數,這個函數爲兩個行爲作state處理,ADD_TODO、REMOVE_TODO。 該reducer函數接收兩個參數,一個state是當前reducer對應的state,action是dispatch傳遞過來的行爲對象。這個函數必定會返回一個新的state。差很少這個意思,不知道代碼寫錯了沒。操作系統

2. redux源碼解析(看着源碼看本節)

兩個核心方法: combineReducers、createStorecode

4.1 Reducers 合併函數 combineReducers對象

用途: 將多個reducer合併成一個。blog

源碼: 

1. 該函數接收一個參數reducers,reducers表明着要合併的全部reducer的鍵值對。

2. redux獲取reducers全部鍵並遍歷,過濾出鍵對應的值是function的項目,生成了最終的reducers對象finalReducers,以防非法reducer值入侵。

3. redux遍歷finalReducers對象並檢查,是否每個函數每一次執行總會返回一個state,並作標記shapeAssertionError

4. 檢查完畢後,回一個閉包函數。該閉包函數就是總的reducer函數combination。

在將來的某個時間,這個combination函數會被執行:

1. 若是shapeAssertionError是真,意味着有錯誤,不執行邏輯。

2. 遍歷finalReducers,拿到每一個key值和reducers函數, 根據key值從state中拿到當前reducer下的當前狀態previousStateForKey, 執行reducer函數並把previousStateForKeyaction傳入, 執行結果一定返回一個nextStateForKey,記住這個state

 

3. 通過一次遍歷後,每個reducer函數都執行並返回了新的state。若是新的state和原來的state一致,返回原來的state,若是不一致,返回新的state

4.2Store 建立函數createStore

用途: 建立store和工具方法

1. 該函數接收三個參數(只說前兩個): reducer(總的reducer函數,combineReducers函數生成的combination函數), preloadedState(自定義的初始化state)

2. 將reducer函數保存在currentReducer變量,初始化一個currentState爲preloadedState或者undefined,後續redux會根據currentState值用reducer函數來初始化state

3.初始化currentListenersnextListeners爲空數組,這兩個數組爲觀察者模式服務,存儲監聽函數。

4.定義一個subscribe函數用來訂閱一個監聽函數,同時返回一個閉包函數unsubscribe,當執行這個unsubscribe函數時,當前監聽函數移除監聽隊列。

5.定義dispatch函數,最核心的函數,其工做很是簡單,執行當前的reducer函數currentReducer,並把當前currentStateaction傳遞過去。經過currentReducer函數咱們能夠獲取到用戶須要下一步獲得的state,存儲在currentState中爲視圖層所用。若是有監聽函數,就遍歷並執行他們。

6.getState函數返回當前state狀態樹。

3. 注意事項

1. 每一次dispatch都會遍歷全部的reducer, 每個reducer能夠對同一行爲作不一樣處理。dispatch要作什麼事,只看type值!

2.每個reducer函數必須有對state爲undefined時的處理,由於redux建立store時會初始化一次store,此時store中尚未任何值。

3. reducer函數是個純函數,只作數據的改變,不作請求、定時器之類的邏輯。

4. 一個store就是一個state的樹狀結構,你只能經過reducer來改變他的數據。

4. 總結

還有一些小函數沒用過也沒看,,,畢竟博主也是個懶熊,,,以上是看源碼獲得的結果。原理很簡單,看一遍源碼就知道了,不看的話還真一臉懵逼。。有些地方可能沒理解透,有老司機能夠指導一二,若有錯誤請指正。

相關文章
相關標籤/搜索