2017.9.10日 教師節 : ~當一個事物你沒有接觸,可是生活中 經常用到他,你就不得不去了解他了。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。差很少這個意思,不知道代碼寫錯了沒。操作系統
兩個核心方法: 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函數並把previousStateForKey和action傳入, 執行結果一定返回一個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.初始化currentListeners、nextListeners爲空數組,這兩個數組爲觀察者模式服務,存儲監聽函數。
4.定義一個subscribe函數用來訂閱一個監聽函數,同時返回一個閉包函數unsubscribe,當執行這個unsubscribe函數時,當前監聽函數移除監聽隊列。
5.定義dispatch函數,最核心的函數,其工做很是簡單,執行當前的reducer函數currentReducer,並把當前currentState和action傳遞過去。經過currentReducer函數咱們能夠獲取到用戶須要下一步獲得的state,存儲在currentState中爲視圖層所用。若是有監聽函數,就遍歷並執行他們。
6.getState函數返回當前state狀態樹。
1. 每一次dispatch都會遍歷全部的reducer, 每個reducer能夠對同一行爲作不一樣處理。dispatch要作什麼事,只看type值!
2.每個reducer函數必須有對state爲undefined時的處理,由於redux建立store時會初始化一次store,此時store中尚未任何值。
3. reducer函數是個純函數,只作數據的改變,不作請求、定時器之類的邏輯。
4. 一個store就是一個state的樹狀結構,你只能經過reducer來改變他的數據。
還有一些小函數沒用過也沒看,,,畢竟博主也是個懶熊,,,以上是看源碼獲得的結果。原理很簡單,看一遍源碼就知道了,不看的話還真一臉懵逼。。有些地方可能沒理解透,有老司機能夠指導一二,若有錯誤請指正。