• Redux:中间件


    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 
    6 let store = createStore(
    7      reducer,
    8     applyMiddleware(thunk)
    9     )

    这是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, applyMiddleware,compose } 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};

  • 相关阅读:
    redis排序【转载】
    程序员必读的30本书(转)
    Linux进程调度程序的具体细节(转)
    汉字转换拼音(网上找的js库)
    虚拟机配置host访问主机web
    301重定向的实现方法(转)
    浏览器关闭后,能继续执行的函数
    awk文本处理总结(转)
    DTD
    DOM编程艺术 4
  • 原文地址:https://www.cnblogs.com/alan2kat/p/7531941.html
Copyright © 2020-2023  润新知