1. 程式人生 > >讀redux有感: redux原來是這樣操作的。

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

司機 remove 項目 入庫 ext 做了 ejs 什麽事 shape

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

註:新手可以看一下,畢竟博主也是個菜鳥,沒法寫高深的東西,不想看博主扯淡的直接看第三節啦~~

1. 生活隨筆

經過半年的不懈努力(找工作),終於再任職了兩個創業公司後,進入到了一個D輪中大型公司。

在上半年,第一份工作做了三個月的nodejs前端(寫node的前端),回學校後就不再去了。回杭州後第二份工作比較坑,老板小人,員工一波一波的離職,我也離職了快2個月,還沒給我工作,這老板人無力吐槽,人做到這種地步真是夠可以了,這第二份工作做得前端,ionic+angular,整個項目架構很亂。然後辭職後,到了目前這家公司。在這裏,基本每天9點左右下班,有時加班到11點,電商公司,沒辦法。經常加班雖然這也不是什麽大事,畢竟人多,技術好,得到了洗禮,還是感覺不錯的。又是一年校招季,有人要來嗎~~。

2. 前言

項目組裏有一位前端同學負責的項目是react + redux 的,她基礎不怎麽好,更何況這redux不像vuex那樣直觀(個人感覺)。所以她經常問我些東西,一些錯誤,一些小算法之類的,還可以解決,對於並沒有用過redux的我來說,從項目層面上來說,我對代碼也是一臉懵逼,經常埋頭看2小時也弄不好一個小功能。主要是弄不清楚原理。看文檔不想看,工作後比較懶了,,,所以,這周末我就看了下redux的源碼,發現了其中的工作流程。。。。

3. 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。差不多這個意思,不知道代碼寫錯了沒。

4. 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狀態樹。

5. 註意事項

1. 每一次dispatch都會遍歷所有的reducer, 每一個reducer可以對同一行為做不同處理。dispatch要做什麽事,只看type值!

2.每一個reducer函數必須有對state為undefined時的處理,因為redux創建store時會初始化一次store,此時store中還沒有任何值。

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

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

6. 總結

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

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