博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【源码解析】redux-thunk
阅读量:6002 次
发布时间:2019-06-20

本文共 2322 字,大约阅读时间需要 7 分钟。

了解了之后,我很好奇Redux中间件是怎么运作的,于是选了最常用的redux-thunk进行源码分析。

此次分析用的redux-thunk源码版本是2.2.0,redux源码版本是3.7.2。并且需要了解

redux中间件都是由redux的applyMiddleware()方法所挂载的

export default function applyMiddleware(...middlewares) {  return (createStore) => (reducer, preloadedState, enhancer) => {    const store = createStore(reducer, preloadedState, enhancer)    let dispatch = store.dispatch    let chain = []    //暴露给中间件的API,所以redux-thunk可以使用形如return (dispatch, getState)=>{}    const middlewareAPI = {      getState: store.getState,      dispatch: (action) => dispatch(action)    }    //将暴露的API给中间件,调用中间件函数,生成中间件返回值函数(为什么返回值是函数?不是函数下面的compose()就报错了)    chain = middlewares.map(middleware => middleware(middlewareAPI))    //组合全部中间件的返回值函数, chain是中间件返回值函数们    //然后reduce起来的函数返回的也是函数,将store原来的dispatch传进去,dispatch函数也是接受一个action并返回一个action,作为中间件链的头部    dispatch = compose(...chain)(store.dispatch)    return {      ...store,      dispatch    }  }}

可以看到redux主要做了以下事情:

  1. 对中间件们使用map,将dispatchgetState传递进去
  2. 使用compose将中间件组合起来,最后传入原生的store.dispatch

compose函数则是简单的将中间件进行串联调用

//compose(funcA, funcB, funcC) 等于 (args)=>funcA(funcB(funcC(args)))export default function compose(...funcs) {  if (funcs.length === 0) {    return arg => arg  }  if (funcs.length === 1) {    return funcs[0]  }  return funcs.reduce((a, b) => (...args) => a(b(...args)))}

最后我们回到redux-thunk

redux-thunk的代码很短,只有短短14行

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;

它对外暴露的是const thunk = createThunkMiddleware();,也就是({dispatch, getState})=>{...}这个函数。

然后经chain = middlewares.map(middleware => middleware(middlewareAPI))传入dispatchgetStatechain里面是next=>{...},进行compose

compose(a,b,c)的返回值是函数(...args)=>a(b(c(...args))),这个函数经调用,传入参数store.dispatch,之后action会在中间件链上进行传递,只要保证每个中间件的参数是action并且将action传递给下一个中间件。

具体到redux-thunk中,它先检查action是否是函数,一般的action都是plain object,如果是函数就应该是由thunk处理。如果不是,传递给nextnext就是下一个中间件。

如果是函数,则调用这个函数并将dispatch, getState, extraArgument传入。这也就是为什么我们需要将thunk action生成函数(注意action和action生成函数的区别)写成() => (dispatch, getState) => {...},传入redux-thunk的action就是(dispatch, getState)=>{...}这个函数

转载地址:http://oadmx.baihongyu.com/

你可能感兴趣的文章
让VMware ESX中的虚拟机随esx开机自动启动
查看>>
Electron Cash钱包存BCH教程
查看>>
自定义key解决zabbix端口监听取值不准确的问题
查看>>
入门级----黑盒测试、白盒测试、手工测试、自动化测试、探索性测试、单元测试、性能测试、数据库性能、压力测试、安全性测试、SQL注入、缓冲区溢出、环境测试...
查看>>
composer 安装 ubuntu 12.04
查看>>
微服务(二)hystrix
查看>>
Performing a thread dump in Linux or Windows--reference
查看>>
推荐系统中常用算法 以及优点缺点对比
查看>>
cocos2d-x v3.2环境配置(现在3.x版本号可以配置该)
查看>>
穷举法解决旅行商问题
查看>>
Go语言标准库之JSON编解码
查看>>
winpcap 发送数据包
查看>>
cisco 出现 %Error opening tftp://255.255.255.255 错误解决办法
查看>>
VIM编辑器
查看>>
IE主页被篡改 地址框变灰
查看>>
linux上架设l2tp+ipsec ***服务器
查看>>
Facebook和用户界面会如何扭曲你说的话
查看>>
安卓混合开发之Cordova,NativeWebView两种实现
查看>>
桶排序
查看>>
石化数字化交付
查看>>