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


2017.9.10日 教師節

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做不同的操作

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、createStore

4.1 Reducers 合並函數 combineReducers

用途: 將多個reducer合並成一個。

源碼: 

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來改變他的數據。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM