閒話不多說,上**。
import thunk from 'redux-thunk';
import rootreducer from './reducers/index';
// create a store that has redux-thunk middleware enabled
thunk
)(createstore);
const store = createstorewithmiddleware(rootreducer);
這顯然是乙個裝飾器模式,通過不同的中介軟體對createstore
方法進行修飾,最後形成新的createstore
方法,那麼建立的store就具有這些中介軟體的特性,
非常出色的設計,驚喜不僅在這,看了之後的**你就更不得不佩服作者的**設計能力。
瞬間覺得別人都是碼神,而我就是碼農有木有/(ㄒoㄒ)/~~
import compose from './compose';
/** * of the redux store. this is handy for a variety of tasks, such as expressing
* asynchronous actions in a concise manner, or logging every action payload.
* * see `redux-thunk` package as an example of the redux middleware.
* * because middleware is potentially asynchronous, this should be the first
* store enhancer in the composition chain.
* * note that each middleware will be given the `dispatch` and `getstate` functions
* as named arguments.
* */
export default
function
(...middlewares)
; chain = middlewares.map(middleware => middleware(middlewareapi));
dispatch = compose(...chain)(store.dispatch);
return ;
};}
這就是redux裡面這個方法的原始碼,其中還一半是注釋有木有。。。本來以為肯定有百來行**的
當然這裡不得不說es6的特性提供了非常多的幫助,所以為了省力吧es6玩透還是灰常有必要的(更別說為了裝x了(^__^) )
從這裡開始**就有點繞了,我們逐行分析
return (next) => (reducer, initialstate) =>
function
(reducer, initialstate)
var store = next(reducer, initialstate);
var dispatch = store.dispatch;
var chain = ;
這裡沒什麼好講的,首先建立了乙個store,這個store就是最原始的通過createstore
建立的store,後兩行只是變數賦值
var middlewareapi = ;
chain = middlewares.map(middleware => middleware(middlewareapi));
dispatch = compose(...chain)(store.dispatch);
這裡是關鍵,必須詳細進行講解。
首先,這邊宣告了乙個middlewareapi
物件,這個物件包含兩個方法:
getstate:store中的getstate方法的引用
dispatch:對本身的dispatch方法進行一次封裝
然後
chain = middlewares.map(middleware => middleware(middlewareapi));
我們來仔細看看這行**,首先我們對所有的中介軟體進行乙個map,map結果就是呼叫中介軟體方法,將middlewareapi
作為引數傳入,
這裡我們拿redux-thunk
中介軟體舉例,來看看乙個中介軟體是長什麼樣子的,傳入的引數又是用來幹嘛的。
export default
function
thunkmiddleware
()
redux-thunk
的功能是讓action支援非同步,讓我們可以在action中跟伺服器進行互動等操作,而他的實現。。。(⊙﹏⊙)b是的,又是這麼幾行**。
我們回顧之前的**,在map所有中介軟體的時候我們呼叫了thunkmiddleware
方法,傳入兩個方法dispatch
和getstate
,然後返回了乙個方法,
我們大致抽象一下,應該如下:
function
(next)
}
chain = middlewares.map(middleware => middleware(middlewareapi));
現在我們知道chain是乙個陣列,每一項是呼叫每個中介軟體之後的返回函式
dispatch = compose(...chain)(store.dispatch);
compose是redux裡面的乙個幫助函式,**如下:
export default
function
compose
(...funcs)
~~(>_<)~~我已經不想再吐槽什麼了,
我們看到這邊先呼叫了compose
函式,傳入了結構後的chain
陣列,然後compose
函式返回的也是乙個函式:
function
(arg)
然後我們把store.dispatch
函式作為arg
傳入這個結果,這裡reduceright可以參考這裡
。那麼這邊得到的結果是什麼呢?
// 假設中介軟體陣列是[a, b, c]
// 那麼結果就是a(b(c(store.dispatch)))
再次結合redux-thunk
來看,我們假設只有乙個中介軟體,那麼最終的dispatch
方法就是
function
(action)
// 這裡的next方法,就是真正的store.dispatch方法
// 這裡的dispatch是(action) => store.dispatch(action)
我們再結合redux-thunk
的使用方法來分析一下,
function
incrementasync
(), 1000);
};}
這是使用redux-thunk
時可以定義的非同步action,我們觸發action的時候呼叫的是
dispatch(incrementasync())
incrementasync
返回的是
function
(dispatch)
, 1000);
}
這個時候我們回想經過中介軟體加工的dispatch
方法:
function
(action)
// 這裡的next方法,就是真正的store.dispatch方法
// 這裡的dispatch是(action) => store.dispatch(action)
action是乙個函式,所以action === 'function' ?
成立,那麼就執行action, 並把中介軟體接收到的dispatch方法((action) => store.dispatch(action)
)方法作為引數傳入,在非同步方法執行完之後再次觸發真正的action。如果action不是非同步的,那麼久直接返回乙個物件,這個時候action === 'function' ?
不成立,就直接呼叫next
,也就是原始的store.dispatch
方法。
我們再接著想,如果我們有許多個中介軟體,那麼沒乙個中介軟體的next
就是下乙個中介軟體直到最後乙個中介軟體呼叫store.dispatch
為止。
以上的**非常繞,建議去專研一下原始碼。這麼精簡的**包含了非常多的函式式程式設計的思想,也用到了裝飾器模式的原理,不得不說:
太燒腦啦/(ㄒoㄒ)/~~原文
redux深入高階
閒話不多說,上 import thunk from redux thunk import rootreducer from reducers index create a store that has redux thunk middleware enabled thunk createstore ...
redux筆記 高階
1 拆分ui元件和容器元件 return value onchange 提交 export 對應的聰明元件 render this state return inputvalue handleinputchange submitdata list deletelist 2 非同步請求可以放在元件中,...
深入理解redux中介軟體
摘自 please call me hr redux middleware 是 redux 的乙個 advanced feature.這個概念並不是很新奇,以為在 koa 裡面早已經實現過了.對比與原生的redux middleware koa 的 middleware 差不多相當於是爸爸級的 le...