2020-6-5 seo達(dá)人
前言
前面幾篇我們就 Redux 展開了幾篇文章,這次我們來(lái)實(shí)現(xiàn) react-thunk,就不是叫實(shí)現(xiàn) redux-thunk 了,直接上源碼,因?yàn)樵创a就11行。如果對(duì) Redux 中間件還不理解的,可以看我寫的 Redux 文章。
實(shí)現(xiàn)一個(gè)迷你Redux(基礎(chǔ)版)
實(shí)現(xiàn)一個(gè)Redux(完善版)
淺談React的Context API
帶你實(shí)現(xiàn) react-redux
為什么要用 redux-thunk
在使用 Redux 過(guò)程,通過(guò) dispatch 方法派發(fā)一個(gè) action 對(duì)象。當(dāng)我們使用 redux-thunk 后,可以 dispatch 一個(gè) function。redux-thunk會(huì)自動(dòng)調(diào)用這個(gè) function,并且傳遞 dispatch, getState 方法作為參數(shù)。這樣一來(lái),我們就能在這個(gè) function 里面處理異步邏輯,處理復(fù)雜邏輯,這是原來(lái) Redux 做不到的,因?yàn)樵瓉?lái)就只能 dispatch 一個(gè)簡(jiǎn)單對(duì)象。
用法
redux-thunk 作為 redux 的中間件,主要用來(lái)處理異步請(qǐng)求,比如:
export function fetchData() {
return (dispatch, getState) => {
// to do ...
axios.get('https://jsonplaceholder.typicode.com/todos/1').then(res => {
console.log(res)
})
}
}
redux-thunk 源碼
redux-thunk 的源碼比較簡(jiǎn)潔,實(shí)際就11行。前幾篇我們說(shuō)到 redux 的中間件形式,
本質(zhì)上是對(duì) store.dispatch 方法進(jìn)行了增強(qiáng)改造,基本是類似這種形式:
const middleware = (store) => next => action => {}
在這里就不詳細(xì)解釋了,可以看 實(shí)現(xiàn)一個(gè)Redux(完善版)
先給個(gè)縮水版的實(shí)現(xiàn):
const thunk = ({ getState, dispatch }) => next => action => {
if (typeof action === 'function') {
return action(dispatch, getState)
}
return next(action)
}
export default thunk
原理:即當(dāng) action 為 function 的時(shí)候,就調(diào)用這個(gè) function (傳入 dispatch, getState)并返回;如果不是,就直接傳給下一個(gè)中間件。
完整源碼如下:
function createThunkMiddleware(extraArgument) {
return ({ dispatch, getState }) => next => action => {
// 如果action是一個(gè)function,就返回action(dispatch, getState, extraArgument),否則返回next(action)。
if (typeof action === 'function') {
return action(dispatch, getState, extraArgument)
}
// next為之前傳入的store.dispatch,即改寫前的dispatch
return next(action)
}
}
const thunk = createThunkMiddleware()
// 給thunk設(shè)置一個(gè)變量withExtraArgument,并且將createThunkMiddleware整個(gè)函數(shù)賦給它
thunk.withExtraArgument = createThunkMiddleware
export default thunk
我們發(fā)現(xiàn)其實(shí)還多了 extraArgument 傳入,這個(gè)是自定義參數(shù),如下用法:
const api = "https://jsonplaceholder.typicode.com/todos/1";
const whatever = 10;
const store = createStore(
reducer,
applyMiddleware(thunk.withExtraArgument({ api, whatever })),
);
// later
function fetchData() {
return (dispatch, getState, { api, whatever }) => {
// you can use api and something else here
};
}
總結(jié)
同 redux-thunk 非常流行的庫(kù) redux-saga 一樣,都是在 redux 中做異步請(qǐng)求等副作用。Redux 相關(guān)的系列文章就暫時(shí)寫到這部分為止,下次會(huì)寫其他系列。
藍(lán)藍(lán)設(shè)計(jì)的小編 http://paul-jarrel.com