React+Redux之redux-thunk作用

redux-thunk 是一個比較流行的 redux 異步 action 中間件。redux-thunk 幫助你統(tǒng)一了異步和同步 action 的調(diào)用方式,把異步過程放在 action 級別解決,對 component 沒有影響。下面通過例子一步步來看看。

異步方法的調(diào)用

store.dispatch({ type: 'SHOW_NOTIFICATION', text: 'You logged in.' })
setTimeout(() => {
  store.dispatch({ type: 'HIDE_NOTIFICATION' })
}, 5000)

這是一個簡單的例子,他做事情很簡單,5s 后關(guān)閉提醒。

在一個被 redux connect 過的 component 中,是如下這個樣子:

this.props.dispatch({ type: 'SHOW_NOTIFICATION', text: 'You logged in.' })
setTimeout(() => {
  this.props.dispatch({ type: 'HIDE_NOTIFICATION' })
}, 5000)

本質(zhì)上兩者沒有區(qū)別,只是被 connect 過的 component 中的 ****this.props**** 有了 ****dispatch**** 屬性。

redux-thunk源碼

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;

export default thunk;

redux-thunk的源碼非常簡潔,出去空格一共只有11行,這11行中如果不算上},則只有8行。最后三行模塊的導(dǎo)出方法很好理解,

// thunk.withExtraArgument的結(jié)果如下
function createThunkMiddleware(extraArgument) {
  return ({ dispatch, getState }) => next => action => {
    if (typeof action === 'function') {
      return action(dispatch, getState, extraArgument);
    }
    return next(action);
  };
}

thunk.withExtraArgument允許給返回的函數(shù)傳入額外的參數(shù),它比較難理解的部分和thunk一樣,如下:

({ dispatch, getState }) => next => action => {
    if (typeof action === 'function') {
      return action(dispatch, getState, extraArgument);
    }
    return next(action);
  }

上述代碼使用函數(shù)參數(shù)的解構(gòu)加上連用三個箭頭函數(shù),顯得非常簡潔,單同時也帶來了理解的困難(這也是箭頭函數(shù)的缺點之一)。把上述代碼在babel REPL中轉(zhuǎn)譯為ES5語法后,我們看到以下結(jié)果:

"use strict";

function createThunkMiddleware(extraArgument) {
  return function (_ref) {
    var dispatch = _ref.dispatch,
        getState = _ref.getState;
    return function (next) {
      return function (action) {
        if (typeof action === "function") {
          return action(dispatch, getState, extraArgument);
        }
        return next();
      };
    };
  };
}

這下,代碼一下子我們能看懂了,不過稍等這里的dispatch,getState,next還有action又是什么?

我們先看看,在reudx中我們?nèi)绾问褂弥虚g件:

let store = createStore(
    reducer,
    applyMiddleware(thunk)
);

看來,要解開dispatch,getState,next,action從哪里來,我們還需要再看看applyMiddleware的源碼,如下:

export default function applyMiddleware(...middlewares) {
  return (createStore) => (...args) => {
    const store = createStore(...args)
    let dispatch = store.dispatch
    let chain = []

    const middlewareAPI = {
      getState: store.getState,
      dispatch: (...args) => dispatch(...args)
    }
    chain = middlewares.map(middleware => middleware(middlewareAPI))
    dispatch = compose(...chain)(store.dispatch)

    return {
      ...store,
      dispatch
    }
  }
}

可以看出其中middleware執(zhí)行時傳入的參數(shù)對象middlewareAPI中確實包含getStatedispatch兩項,next則來自dispatch = compose(...chain)(store.dispatch)這一句中的store.dispatch,而actiondispatch某個action時傳入。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容