Redux很早前看過源碼,不得不說Redux是一個有用的架構,接觸過Redux對於以後理解React-Redux有很大的幫助。最近學習了一段時間後打算從新學習下,一方面爲了總結和概括,另外一方面分享給你們,若是有什麼不足之處但願各位大牛的糾錯和指正。本文主要包含以下幾個分析點:javascript
// 該文件的核心函數部分共傳入了三個參數
// reducer, preloadedState, enhancer
function createStore(reducer, preloadedState, enhancer){
...
if (typeof enhancer !== 'undefined') {
return enhancer(createStore)(reducer, preloadedState)
}
...
}
複製代碼
createStore
方法的做用是用來建立一個倉庫來存放state,subscribe,reducer以及dispatch,state用來存放數據的地方,經過store.getState()來獲取;subscribe用來加入監聽函數,當頁面數據改變的時候會進行觸發,dispatch用來派發action,根據不一樣的類型匹配不一樣的reducer,繼而進行state數據的更新,具體能夠參考阮一峯老師的博客 Redux 入門教程。html
其中enhancer
函數的做用顧名思義就是用來擴展增強的,這個函數的存在使得能夠隨意的加入早就想要的中間件,從而更加方便快捷,這裏的增強函數主要是applyMiddleware
。java
export default function applyMiddleware(...middlewares) {
return (createStore) => (reducer, preloadedState, enhancer) => {
// 建立倉庫
const store = createStore(reducer, preloadedState, enhancer)
let dispatch = store.dispatch
let chain = []
const middlewareAPI = {
getState: store.getState,
dispatch: (action) => dispatch(action) // 經過閉包引用外部的dispatch變量
}
// 將middlewareAPI傳入中間件,使得每一箇中間件都得到{getState,dispatch}參數,而因爲閉包的緣由,咱們就能夠在中間件當中獲取最新的store以及引用外部更新的dispatch變量。
// @return 返回包含(next) => (action) => {....}的數組
chain = middlewares.map(middleware => middleware(middlewareAPI))
// 建立加強功能的dispatch
dispatch = compose(...chain)(store.dispatch)
return {
...store,
dispatch
}
}
}
複製代碼
function createThunkMiddleware(extraArgument) {
return ({ dispatch, getState }) => next => action => {
if (typeof action === 'function') {
return action(dispatch, getState, extraArgument);
}
return next(action);
};
}
const thunk = createThunkMiddleware();
thunk.withExtraArgument = createThunkMiddleware;
複製代碼
理解compose方法首先須要瞭解reduce,reduce()方法接收一個函數做爲累加器,數組中的每一個值(從左到右)開始縮減,最終計算爲一個值,因此最終的形式是a(b(c(d...(...args))))
。redux
export default function compose(...funcs) {
if (funcs.length === 0) {
return arg => arg
}
if (funcs.length === 1) {
return funcs[0]
}
return funcs.reduce((a, b) => (...args) => a(b(...args)))
}
複製代碼
以前chain返回包含(next) => {...}的thunk,logger中間件數組,從而獲得a_middleware方法裏的next方法就是b_middleware,b_middleware方法裏的next方法是c_middleware,以此類推,根據applyMiddleware.js
中compose(...chain)(store.dispatch)
以及chain返回值
能夠知道, 最後的next參數是dispatch,大概步驟以下:數組
(action)=>{next=store.dispatch}
[1]函數;[1]
傳給b_middleware的中間件的next,這時候中間件b_middleware內部的next就變成(action)=>{[1]}
[2], 當執行b_middleware的時候,會進入c_middleware;[2]
的結果傳遞給a_middleware, (action)=>(action)=>{[1]}傳遞給a-middleware的next變量,當執行a_middleware的時候會進入b_middleware。從下面大概例子能夠看出disatch: (...args) => dispatch(...args)
的好處,dispatch隨時隨地隨着dispatch = compose(...chain)(store.dispatch)
更新而更新,從而當傳入爲方法的時候,也不會忽略其餘中間件,再次dispatch的時候會流過全部thunk以後的中間件。閉包
1.
a_middleware(b_middleware){
...
b_middleware = (action) => (action) => {store.dispatch函數}
return (action) => b_middleware(action)
...
}
dispatch = (action) => {
if (typeof action === 'function') {
return action(dispatch, getState, extraArgument);
}
return b_middleware(action)
}
2.
b_middleware(c_middleware){
...
c_middleware = (action) => {store.dispatch函數}
return (action) => c_middleware(action)
...
}
dispatch = (action) => {
return c_middleware(action)
}
3.
c_middleware(store.dispatch){
return (action) => {store.dispatch函數}
}
dispatch = (action) => {store.dispatch函數}
複製代碼
1.首先將store.getState
和store.dispatch
經過閉包的方式使得中間件能夠訪問;架構
2.其次,經過compose
函數操做,對next進行賦值,使得中間件按順序依次執行;app
3.最後,返回一個dispatch函數
,能夠經過傳入action參數,使得中間件按順序依次執行,若是action爲函數則直接執行該函數,而且傳入dispatch和getSate參數。異步
總之使用redux進行狀態管理極大地提升了工做效率,讓數據更好地被管理。函數