为了账号安全,请及时绑定邮箱和手机立即绑定

【九月打卡】第十八天 Redux

标签:
redux

课程:React18 系统精讲

章节:Redux中间件

讲师:阿莱克斯刘

课程内容

【中间件】什么是中间件

上节课,我们学习了redux-thunk,初步了解了redux中间件的的作用。本节课,我们来学习一下中间件的原理。

函数式编程概念

在学习中间件之前,我们还是得先补充一点关于函数式编程的基础知识。不过如果同学们已经自学成才了,那么可以跳过这部分的内容。

复合函数

所谓函数式编程,其实就是在做数学题,比如复合函数。学过高中数学我们都知道函数是可以组合的,对吧。

比如说,我们现在有这么两个函数


f(x) = x^2 + 2x + 3

g(x) = 2x


那么,如果我们把两个函数组合起来可以怎么写呢?


(f * g)(x) = f(g(x)) = f(2x) = 2x^2 + 4x + 6


以上就是数学角度的复合函数,而实际上,在我们的函数式编程中也是完全符合这样的定义的。我们来再来看个例子,演示组合两个函数并返回一个新的函数:

  • 首先,我们有一个 hello 函数,输出一个字符串

const  hello = function (x) {

return  `Hello, ${x}`;

};


  • 然后,我们还有一个happy 函数,输出的是一个笑脸

const  happy = function (x) {

return  `${x} :)`;

};


  • 除此之外,我们还有一个组合函数compose,参数接受两个函数,可以把这两个函数按照组合起来。

const  compose = function (f, g) {

return  function (x) {

return  f(g(x));

};

};


  • 最后,我们就可以使用这个compose把hello和happy组合起来了

var  happyHello = compose(hello, happy);


  • 于是,当我们调用happyhello这个函数的时候,他的输出结果就是两个函数组合而成的,比如说,参数传入“阿莱克斯”,那么最后的输出就是:

happyHello("阿莱克斯")

// 输出: Hello, 阿莱克斯 :)


柯里化

复合函数是redux中间件的基础,而柯里化就是实现中间件落地的技术。除此以外,另一个吊炸天的函数式编程概念就是,柯里化。来看下面这个例子,我们可以通过柯里化来组合你的函数,创建一个强大的数据处理管道。

比如说,我们有一个加法计算器,curriedAdd 。通过柯里化,给函数传入第一部分的参数;然后,赋值定义给另一个函数,addTen;最后,在调用addTen函数的时候传入第二部分的参数。


const  curriedAdd = (a) => {

return (b) => { return  a + b}

};

const  addTen = curriedAdd(10);

addTen(10); //20


这时候,两次参数的传递就被积累起来,最后进入curriedAdd函数,进行最终处理。

从原理上来说,如果写成箭头函数的形式,会更容易理解一点,其实原理上就是一个函数的函数。


// 原理

const  curriedAdd = (a) => (b) =>  a + b


为什么需要中间件?

ok,基础知识补充完成,接下来,回到我们的主题,redux中间件。那么,我们为什么会需要中间件?

经过之前的课程,我们知道redux的核心,就是控制和管理所有的数据输入输出,因此有了store、reducer以及action 的 dispatch。

产品经理跑过来提了一个需求

假如现在产品经理跑过来提了一个需求,要求我们的网站可以记录每次dispatch的action信息,我们怎么办呢?最简单直接的办法就是在每一个dispatch的前面加上console.log,然后再dispatch,对吧:


console.log('dispatching', action);

dispatch(action)


产品经理又来了

ok,过了两天这个产品经理又来了,这次他说,我需要每次dispatch还得记录一下当前store的数据state,我们怎么办呢?然后我们又需要在对每一个dispatch做修改


console.log('dispatching', action);

console.log('当前 state', store.getState());

dispatch(action)


但是,如果我们的程序中有很多的dispatch,我们就需要添加很多的重复代码,虽然编辑器可以批量替换,但这无疑是产生了很多同样的模版代码。因此,我们有没有可能重写一下原本的dipatch函数,把日志打印的功能加进去呢?

当然是可以的,我们只需要对原本的dispatch函数进行一下封装就可以了,大概的封装就是这个样子:


let  next = store.dispatch

store.dispatch = function  dispatchAndLog(action) {

console.log('dispatching', action)

console.log('当前 state', store.getState());

next(action)

}


产品经理没完没了

好了,如果这个时候产品经理又跑过来了,这次他要求,我们不仅要打印当前state,还得打印更改后的state。那么,我们这次又该如何处理呢?很简单,只需要在执行完dispatch next aciton以后,也就是当state发生改变以后,我们直接console log打印state数据就好了。


let  next = store.dispatch

store.dispatch = function  dispatchAndLog(action) {

console.log('dispatching', action)

console.log('当前 state', store.getState());

next(action)

console.log('更改后的 state', store.getState());

}


那么,如果把这个入口封装一下,给未来的拓展做更广泛的应用,那么,我们可以把整个流程都写在函数里来处理,函数名称叫做,applyMiddleware。


const  applyMiddleware = function(middleware){

let  next = store.dispatch;

// 这里传入store,因为中间件中有可能会用到getState获取数据,比如打印store

store.dispatch = middleware(store)(next);

}

applyMiddleware(dispatchAndLog)


我们通过把中间件middleware传入函数,使用克丽化来传递参数store和dispatch,然后使用中间件来代理sotre原有的dipatch函数,通过截获所有进入store中的action,来对某些aciton做特殊的处理,比如consolo log打印日志、异步处理等等

Redux中间件机制

简单来讲,Redux middleware 提供了一个分类处理 action 的机会。在 middleware 中,我们可以检阅每一个传递给store的 action,并且挑选出特定类型的 action 进行相应操作。

没有中间件

这样说起来可能会有点抽象,我们直接来看图,这是在没有中间件情况下的 redux 的数据流:

sRTpNQ.png

这是很经典的一个redux 的数据流的过程,用户点击button,然后dipatch action,reducer拿到action以后改变state,推送给view重新渲染ui。

增加了中间件

但在增加了 middleware 后,我们就可以在这途中对 action 进行截获,并根据action的类型做出相应的处理。

而 redux middleware 的理论基础的就是复合函数,所以,不同的中间件可以自由组合,而数据也会依次传递。也正是由于这个机制,我们便可以通过串联middleware的形式来满足日常的开发需求,每一个 middleware 都可以处理一个独立的业务需求。

sRT9hj.png

比如我们现在看到的流程图,派发给 redux Store 的 action 对象,会被 Store 上的多个中间件依次捕获。如果把 action 和当前的 state 交给 reducer 处理的过程看做默认存在的中间件,那么其实所有的对 action 的处理都可以有中间件组成的。

值得注意的是这些中间件会按照指定的顺序依次处理传入的 action,只有排在前面的中间件完成任务后,后面的中间件才有机会继续处理 action,同样的,每个中间件都有自己的“熔断”处理,当它认为这个 action 不需要后面的中间件进行处理时,后面的中间件就不能再对这个 action 进行处理了。

而不同的中间件之所以可以组合使用,是因为 Redux 要求所有的中间件必须提供统一的接口,每个中间件的尉氏县逻辑虽然不一样,但只要遵循统一的接口就能和redux以及其他的中间件对话了

redux的异步处理

在多种中间件中,处理 redux 异步事件的中间件,绝对占有举足轻重的地位。这个部分我们上节课已经解决了,使用的技术是redux-thunk。除了thunk,reudx还有其他的异步处理中间件,比如说redux-promise、redux-saga等等。从原来上来说,这些插件其实都是换汤不换药,基本的原理都一样,他们都代表了各自解决redux异步流管理问题的方案。

  • redux-thunk

  • redux-promise

  • redux-saga

Redux中间件公式


const  middleware = (store) => (next) => (action) => { }


下面的公式是Redux中间件的公式,请大家记住这个公式,我们下节课将会利用这个公式,创建一个自定义中间件,来实现课程中产品经理提出的业务要求。

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消