redux中间件概念 比较容易理解。

在使用redux时,改变store state的一个固定套路是调用store.dispatch(action)方法,将action送到reducer中。

所谓中间件,就是在dispatch发送action  和  action到达reducer  之间,加入一些中间层,对action进行处理。

在之前学习redux的异步操作时,用到的redux-thunk就是一个中间件。action抵达reducer之前先对其进行判断,如果是对象就直接送到reducer;如果是函数就执行。

中间件特点:

1.是一个独立的函数,与其他中间件没有依赖关系

2.中间件可以有多个,按顺序组合使用

3.有统一的接口

中间件说白了就是一些第三方的插件,用来增强dispatch的功能,让我们可以在action到达reducer之前对action作出判断、改造、log下信息、实现复杂逻辑等。

当我们使用了多个中间件时,action依次从前一个中间件传到下一个中间件,最后抵达reducer。也可能在某个中间件进行处理后,发现没必要传到reducer了,就不传给下一个中间件(相当于丢弃,不再去处理)。

中间件必须定义为一个函数,它的基本结构如下:

  1. function middleWare({dispatch,getState}){
  2. return function(next){
  3. return function(action){
  4. return next(action)
  5. }
  6. }
  7. }

中间件接收store的dispatch和getState方法

中间件返回一个接收next参数的函数,next参数自身是一个函数。中间件调用next函数告诉redux处理工作已经完成,将action传递给下一个中间件

中间件返回的函数(第二行),又返回一个带参数action的函数,这个函数里对action进行处理

我们可以发现中间件函数的设计,对函数进行了柯里化,遵循了函数式编程的思想。每个函数都有纯粹而明确的功能,通过嵌套组合实现更复杂的功能。

使用中间件:

  1. import { createStore, applyMiddleware } from 'redux';
  2. import thunk from 'redux-thunk';
  3. import reducer from './reducers'
  4.  
  5. let store = createStore(
  6. reducer,
  7. applyMiddleware(thunk)
  8. )

这是npm上redux-thunk文档给的使用使用该中间件的实例代码。使用中间件,需要用到redux的applyMiddleware方法。

在《深入浅出React和redux》一书中,作者倒是给出了两种使用中间件方式,代码不太一样:

1.针对简单场景:

  1. import { createStore, applyMiddleware } from 'redux';
  2. import thunk from 'redux-thunk'
  3.  
  4. //这里applyMiddleware执行后产生的是一个Store Enhancer函数,
  5. //Store Enhancer又将redux的createStore作为参数,生成一个加强版的创建store的函数
  6. const configureStore = applyMiddleware(thunk)(createStore);
  7. const store = configreStore(reducer,initialState);

这里的代码虽然跟上一段代码不太一样,但是其实逻辑是一样的。因为createStore的第三个参数就是一个Store Enhancer,当只有两个参数且第二个参数是函数时,就当作Enhancer。applyMiddleware(thunk)的执行结果就是一个Enhencer。

作者说“利用configureStore创造的store将具有中间件的功能”。效果是一样的。

2.针对使用其他Store Enhancer的场景,作者说,实际中我们常常会使用不止一种SE,所以更通常的情况是:用redux提供的compose方法将applyMiddleware的返回函数和其他SE组装成一个Store Enhancer,传入createStore中。

  1. import { createStore, applyMiddlewarecompose } from 'redux';
  2. import thunk from 'redux-thunk'
  3.  
  4. const win=window;
  5. const storeEnhancer = compose(
  6. applyMiddleware(...middlewares),
  7. (win && win.devToolsExtension)?win.devToolsExtension():f=>f);
  8. );
  9. const store = creatorStore(reducer,storeEnhancer);

其中applyMiddleware必须作为compose的第一个参数,因为中间件的顺序也是它们处理action的顺序,其他SE如果不能识别action,会报错。

中间件实现:

  1. function isPromise(obj){
  2. return obj && typeof obj.then === 'fuction'
  3. }
  4.  
  5. export default function PromiseMiddleware((dispatch)){
  6. return function(next){
  7. return function(action){
  8. return isPromise(action)?action.then(dispatch):next(action);
  9.  
  10. }
  11. }
  12. }

这是书上的一个未改进的例子,redux中某一类型的函数总有固定的套路。这段代码判断action是否promise,并执行对应操作。遵循着MiddleWare=>(next)=>(action)=>{next(action)}的套路。

程墨强调,开发中间件时要记住两个原则:

1.中间件应该独立存在,在功能和顺序上不依赖于其他中间件

2.应该考虑到当前有多个中间件存在,要通过next(action)将action交还给中间件管道

Store Enhancer:

中间件可以定制增强dispatch方法,但也只是对于dispatch方法。要增强store,需要使用store enhancer。applyMiddleware的返回值其实就是个SE,通过SE可以增强store的各个方面。

我们知道createStore方法接收三个参数(reducer,initialState,storeEnhancer).storeEnhancer是一个函数,接收createStore模样的函数作为参数,返回一个新的createStore。

  1. //一个什么都不做的SE
  2. const doNothingSE = (createStore)=>(reducer,preState,enhancer)=>{
  3. const store = createStore(reducer,preState,enhencer);
  4. return store;
  5. };
  6. //每次dispatch都log下action的SE
  7. const doNothingSE = (createStore)=>(reducer,preState,enhancer)=>{
  8. const store = createStore(reducer,preState,enhencer);
  9. const originDispatch = store.dispatch;
  10. store.dispatch=(action)=>{
  11. console.log('dispatch action: ' + action );
  12. originDispatch(action);
  13. }
  14. return store;
  15. };

可以看出,SE的基本套路是将原来的成员函数的引用保存下来,然后写一个新的实现,在新的实现里添加额外功能代码,然后调用原来的成员函数,从而达到扩展功能的目的。

出了增强原有方法的功能外,还可以给store添加新方法,比如在函数体内定义一个newMethod,return {...store,newMethod};

Redux:中间件的更多相关文章

  1. react+redux教程(七)自定义redux中间件

    今天,我们要讲解的是自定义redux中间件这个知识点.本节内容非常抽象,特别是中间件的定义原理,那多层的函数嵌套和串联,需要极强逻辑思维能力才能完全消化吸收.不过我会多罗嗦几句,所以不用担心. 例子 ...

  2. 【React全家桶入门之十三】Redux中间件与异步action

    在上一篇中我们了解到,更新Redux中状态的流程是这种:action -> reducer -> new state. 文中也讲到.action是一个普通的javascript对象.red ...

  3. redux中间件和redux-thunk实现原理

    redux-thunk这个中间件可以使我们把这样的异步请求或者说复杂的逻辑可以放到action里面去处理,redux-thunk使redux的一个中间件,为什么叫做中间件 我们说中间件,那么肯定是谁和 ...

  4. Redux 中间件与函数式编程

    为什么需要中间件 接触过 Express 的同学对"中间件"这个名词应该并不陌生.在 Express 中,中间件就是一些用于定制对特定请求的处理过程的函数.作为中间件的函数是相互独 ...

  5. 3.3 理解 Redux 中间件(转)

    这一小节会讲解 redux 中间件的原理,为下一节讲解 redux 异步 action 做铺垫,主要内容为: Redux 中间件是什么 使用 Redux 中间件 logger 中间件结构分析 appl ...

  6. 理解 Redux 中间件机制

    Redux 的 action 是一个 JS 对象,它表明了如何对 store 进行修改.但是 Redux 的中间件机制使action creator 不光可以返回 action 对象,也可以返回 ac ...

  7. react第十八单元(redux中间件redux-thunk,redux工程目录的样板代码,规范目录结构)

    第十八单元(redux中间件redux-thunk,redux工程目录的样板代码,规范目录结构) #课程目标 中间件:中间件增强redux的可扩展性,实现功能复用的目的. redux-thunk异步逻 ...

  8. redux 中间件 redux-saga 使用教程

    redux 中间件 redux-saga 使用教程 redux middleware refs https://redux-saga.js.org/docs/ExternalResources.htm ...

  9. redux中间件

    Redux 中间件 什么是中间件? 中间件本质上就是一个函数,Redux允许我们通过中间件的方式,扩展和增强Redux应用程序,增强体现在对action处理能力上,之前的计数器与弹出框案例中.acti ...

随机推荐

  1. Netty 中的心跳检测机制

    心跳检测一般存在于建立长连接 或者 需要保活的场景. 心跳的使用场景 长连接的应用场景非常的广泛,比如监控系统,IM系统,即时报价系统,推送服务等等.像这些场景都是比较注重实时性,如果每次发送数据都要 ...

  2. Matplotlib 误差线的绘制和子图的创建方式

    一.绘制误差线 使用errorbar方法可以绘制误差线. x = np.linspace(0,10,50) dy=0.8 y = np.cos(x) + dy*np.random.randn(50) ...

  3. 005.Ansible de palybook简单使用

    一 Ansible Playbook简介 ansbile-playbook是一系列ansible命令的集合,利用yaml 语言编写.playbook命令根据自上而下的顺序依次执行.同时,playboo ...

  4. php 推荐密码加密的方法

    password_hash() 函数 password_hash() 函数用于创建密码的散列(hash) PASSWORD_DEFAULT - 使用 bcrypt 算法 (PHP 5.5.0 默认). ...

  5. Linux系统管理第五六七章 权限及归属管理 磁盘管理 文件系统与lvm

    第五六七章   alias 查看系统别名   67 chmod 设置文件或目录的权限 -R表示以递归的方式设置目录及目录下的所有子目录及文件的权限 u:属主 g:属组 o:其他人 a:所有人 +:添加 ...

  6. 【集群实战】NFS服务常见故障排查和解决方法

    NFS,全名叫Network File System,中文叫网络文件系统,是Linux.UNIX系统的分布式文件系统的一个组成部分,可实现在不同网络上共享远程文件系统. NFS由Sun公司开发,目前已 ...

  7. Vue中的父子传值问题

    个人网站 https://iiter.cn 程序员导航站 开业啦,欢迎各位观众姥爷赏脸参观,如有意见或建议希望能够不吝赐教! 好久没更博了,感觉下班后的时间莫名其妙就没有了,有了,了... 趁着端午放 ...

  8. windows下遍历文件夹

    Github地址 函数: HANDLE WINAPI FindFirstFile( _In_ LPCTSTR lpFileName, _Out_ LPWIN32_FIND_DATA lpFindFil ...

  9. postman(动态数据获取)

    一:返回报文为 json 格式 示例:因为充值记录接口中需要用到登录接口返回报文中的信息如下 1.以获取token(JWT)和uid为例 2.在登录接口的tests中写入代码(因为登录接口报文信息中有 ...

  10. 【原创】Linux Mutex机制分析

    背景 Read the fucking source code! --By 鲁迅 A picture is worth a thousand words. --By 高尔基 说明: Kernel版本: ...