redux源碼閱讀——applyMiddleware

redux源碼——applyMiddleware

相關(guān)源碼展示

applyMiddleware源碼

export default function applyMiddleware(...middlewares) {
  return (createStore) => (reducer, preloadedState, enhancer) => {
    var store = createStore(reducer, preloadedState, enhancer)
    var dispatch = store.dispatch
    var chain = []

    var middlewareAPI = {
      getState: store.getState,
      dispatch: (action) => dispatch(action)
    }
    // ### step1
    chain = middlewares.map(middleware => middleware(middlewareAPI))
    // ### step2
    dispatch = compose(...chain)(store.dispatch)

    return {
      ...store,
      dispatch
    }
  }
}

compose函數(shù)源碼

export default function compose(...funcs) {
  if (funcs.length === 0) {
    return arg => arg
  }

  if (funcs.length === 1) {
    return funcs[0]
  }

  const last = funcs[funcs.length - 1]
  const rest = funcs.slice(0, -1)
  // ### step3
  return (...args) => rest.reduceRight((composed, f) => f(composed), last(...args))
}

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;

初始化調(diào)用部分的代碼

import thunk from 'redux-thunk'
import createLogger from 'redux-logger'
import reducer from './reducers'

const middleware = [ thunk ]
if (process.env.NODE_ENV !== 'production') {
  middleware.push(createLogger())
}

const store = createStore(
  reducer,
  applyMiddleware(...middleware)
)

action中調(diào)用的代碼

const fetchPosts = reddit => dispatch => {
  dispatch(requestPosts(reddit))
  return fetch(`https://www.reddit.com/r/${reddit}.json`)
    .then(response => response.json())
    .then(json => dispatch(receivePosts(reddit, json)))
}

源碼分析

做了什么

就是在原先同步dispatch action這條路上,根據(jù)middleware加入了一層一層的處理,而對于redux-thunk,其實(shí)就是將異步的action的返回替換為同步的action返回,先返回一個start的action,然后等resolve了之后,再返回一個resolve的action

step1

剝離middleware的第一層,拿redux-thunk舉例,剝離之后,應(yīng)該是這樣的

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

  return next(action);
};

step2 & step3

這兩段是為了將每個middleware再次剝離之后,然后再套起來,類似俄羅斯套娃那樣,比如兩個middleware是這樣的[thunk, logger],那么經(jīng)過這兩段代碼處理之后,thunk的next就是logger,logger的next就是原先的dispatch(store.dispatch)

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

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

  • http://gaearon.github.io/redux/index.html ,文檔在 http://rac...
    jacobbubu閱讀 80,409評論 35 198
  • 為什么dispatch需要middleware 上圖表達(dá)的是 redux 中一個簡單的同步數(shù)據(jù)流動的場景,點(diǎn)擊 b...
    一個胖子的我閱讀 2,122評論 1 9
  • 一、什么情況需要redux? 1、用戶的使用方式復(fù)雜 2、不同身份的用戶有不同的使用方式(比如普通用戶和管...
    初晨的筆記閱讀 2,129評論 0 11
  • Redux入門學(xué)習(xí)系列教程(一)Redux入門學(xué)習(xí)系列教程(二)Redux入門學(xué)習(xí)系列教程(三)Redux入門學(xué)習(xí)...
    光強(qiáng)_上海閱讀 2,675評論 0 9
  • “中間件”這個詞聽起來很恐怖,但它實(shí)際一點(diǎn)都不難。想更好的了解中間件的方法就是看一下那些已經(jīng)實(shí)現(xiàn)了的中間件是怎么工...
    Jmingzi_閱讀 1,770評論 1 7

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