理解 redux-thunk 源碼

前言

前面幾篇咱們就 Redux 展開了幾篇文章,此次咱們來實現 react-thunk,就不是叫實現 redux-thunk 了,直接上源碼,由於源碼就11行。若是對 Redux 中間件還不理解的,能夠看我寫的 Redux 文章。javascript

爲何要用 redux-thunk

在使用 Redux 過程,經過 dispatch 方法派發一個 action 對象。當咱們使用 redux-thunk 後,能夠 dispatch 一個 function。redux-thunk會自動調用這個 function,而且傳遞 dispatch, getState 方法做爲參數。這樣一來,咱們就能在這個 function 裏面處理異步邏輯,處理複雜邏輯,這是原來 Redux 作不到的,由於原來就只能 dispatch 一個簡單對象。java

用法

redux-thunk 做爲 redux 的中間件,主要用來處理異步請求,好比:react

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 的源碼比較簡潔,實際就11行。前幾篇咱們說到 redux 的中間件形式,
本質上是對 store.dispatch 方法進行了加強改造,基本是相似這種形式:ios

const middleware = (store) => next => action => {}

在這裏就不詳細解釋了,能夠看 實現一個Redux(完善版)git

先給個縮水版的實現:github

const thunk = ({ getState, dispatch }) => next => action => {
    if (typeof action === 'function') {
        return action(dispatch, getState)
    }
    return next(action)
}
export default thunk
  • 原理:即當 action 爲 function 的時候,就調用這個 function (傳入 dispatch, getState)並返回;若是不是,就直接傳給下一個中間件。

完整源碼以下:json

function createThunkMiddleware(extraArgument) {
  return ({ dispatch, getState }) => next => action => {
    // 若是action是一個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設置一個變量withExtraArgument,而且將createThunkMiddleware整個函數賦給它
thunk.withExtraArgument = createThunkMiddleware

export default thunk

咱們發現其實還多了 extraArgument 傳入,這個是自定義參數,以下用法:redux

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
  };
}

總結

同 redux-thunk 很是流行的庫 redux-saga 同樣,都是在 redux 中作異步請求等反作用。Redux 相關的系列文章就暫時寫到這部分爲止,下次會寫其餘系列。axios