为了账号安全,请及时绑定邮箱和手机立即绑定
首页 手记 【九月打卡】第十七天 redux

【九月打卡】第十七天 redux

2022.09.22 22:23 42浏览

课程:React18 系统精讲

章节:Redux中间件

讲师:阿莱克斯刘

课程内容

【中间件】使用redux-thunk中间价实现异步action
上节课,我们综合运用了前一章整章的知识,完成了home页面的redux架构。但是还有一个小问题值得我们关注,请同学们打开homepage文件。在componentDidMount函数中,我们在初始化推荐列表数据的时候调用了一个api请求.


我们可以这样思考一下刚刚提到的几个问题。现在,推荐列表的数据是在主页启动的时候通过调用api来获得数据的,api是由主页触发的。那么我们可以想象一下,在某个页面也需要使用到推荐列表的数据,可是这个人可能是通过url直接访问到这个页面跳过了主页,那么这个时候推荐列表会有数据存在吗?很明显没有嘛,除非我们在这个页面也同样协商调用api的代码。但是这样处理后的代码会非常凌乱,而且违背了我们写代码的 DRY 原则,就是do not repeat yourself不要重复代码这个原则。一个或者两个组件你这样处理可能还能受得了,但是如果我们有成百上千个这样的复用组件同时发送action、调用api,那么同学们可以想象这样的代码基本上就是一个不可维护的状态了。

所以,我们唯一的选择就是把数据获取的逻辑从组件也就是UI中剥离处理,放进store,由store统一处理。我这里说的数据获取的逻辑,并不仅限于api数据调用,也包括异步读取浏览器数据、读取文件数据、读取数据库数据等等等等。但是,store中的那个部分来处理类似api调用这样的操作呢?action吗?他返回的是一个aciton对象,而不是过程,我们没有办法在action中处理状态的变化。那放在reudcer中可以吗?当然也是不行的,原因很简单,reducer是纯函数,不能处理副作用,而api请求就是一个不折不扣的副作用。
中间件
所以,我们就需要一个新的模块来处理副作用了,请同学们回忆一下我们第七章讲解redux时候画的架构图,我们处理副作用的模块就是中间件。

那么中间件是什么?他的实现原理又是什么呢?在这里,我先卖个关子,请同学们这节课先跟着老师来完成代码,下节课我们再探究原理。
redux-thunk
接下来,我将会带着同学们使用中间件来完成api请求的异步处理。对于异步处理,redux给出了一个官方的中间件,叫做redux-thunk,这个中间件几乎每个react程序员必须掌握的基本技能之一。我们先来看一下他的源代码,百度搜索redux thunk,点击github这个搜索结果。点开src文件夹,再点开index.js,同学们没看错,这个大名鼎鼎中间件包含空行一共才14行代码。这就是所谓浓缩就是精华,其实他的代码就是这么简单,他仅仅是让dispath多支持了一种类型,就是函数类型。

另外,值得一提的是,如果我们回到src文件夹,能看到这里有一个inde.d.ts的文件,这就是typescript的声明,也就是说thunk虽然不是使用typescript写的,但是他却自带typescript的说明文件,所以我们直接安装就能使用。

好了,我们从原理上知道了thunk要干什么,那么让我们回到项目开始代码吧。首先,安装这个中间件,打开命令行,

redux-thunk自带typescript,所以直接使用。使用方法也挺简单,打开我们的store.ts,引入redux-thunk。 然后,再从redux中引入applyMiddleware函数。最后,在createStore的第二个参数中,把applyMiddleware以及thunk放进去。

大功告成,thunk中间件创建完成。不过,同学们不要高兴得太早,本节课的难点现在才开始。

首先请同学们思考一下我们使用thunk的目的是什么?打开主页,homepage.tsx,我们的目的是是要把home页面中关于api请求的异步处理代码挪到store中去,对吧。也就是说在componentDidMount函数中,等一下这一大坨代码全部都会被删除,取而代之的是dispatch一个名叫“给我数据”的action,store收到这个action以后就开始自动执行从api 请求开始、到api处理、到请求成功、或者请求失败的整个过程。而这一切对于主页来说,都应该是隐藏起来的,主页只负责向store索取数据、然后在jsx中渲染数据。

ok,其实这里只是一段pseudo code 伪代码,我们先把思路列在这里,等会等我们aciton的代码处理完毕以后在回来修正。

那么既然要dispatch一个action,我们是不是先要创建这个aciton的创建工厂呢?请同学们打开recommendProductsAction.ts,新的action creator就叫做,给我数据,giveMeDataActionCreator

不过,还记得我们刚刚在讲解redux-thunk源码的时候说过,thunk的作用就是让dispath多支持了一种类型,就是函数类型。现在这个giveMeDataActionCreator 就派上用场了,他的返回类型不只是对象action而是一个函数,而这个函数的类型就是thunk的action类型。

请同学们从react-thunk中引入ThunkAction类型

然后把giveMeDataActionCreator 函数的返回类型定义为ThunkAction。不过,报错了。

请把鼠标放在ThunkAction上,我们会看到这个ThunkAction的范型定义非常复杂,他有四个参数,

第一个是当前函数的返回值R,代表return,要求我们定义最终输出类型,不过我们的giveMeDataActionCreator是个返回函数的类型,所以最终输出是void,也就是没有任何数据输出。
第二个参数S比较简单,指的是StoreState,需要输入的是我们store的类型,也就是rootstate,请同学们从store中引入rootstate
第三个参数E,代表extra,意思就是定义一下我们action中额外的参数,不过我们没参数,所以是unknow,或者也可以写undefined。
最后一个A,就是我们的action,我们直接使用混合aciton类型RecommendProductAction就可以了
不过,根据ThunkAction给出的类型定义,我们还需要给函数的函数添加两个参数,第一个是dispatch,第二个是getState。同学们看到这两个参数的名字就应该知道怎么使用了吧?我就不多说了。

现在,aciton函数的报错消失了,我们接下来把主页中原本应该从componentDidMount中删掉的代码粘贴在这里。

粘贴过来以后,修正一下代码,改使用dispatch的地方都改为dispatch,然后给函数开头加上async关键词,await 的报错也就消失了。

好了,使用thunk处理异步逻辑的aciton creator创建完毕了,在这个aciton creator中,我们将会连续发送至少两个action,每次发送action以后,reducer都会执行相对应的操作。而我们的中间件将会持续执行知道异步逻辑全部结束。

接下来,我们回到主页,把componentDidMount中的伪代码改为真代码。

从action中引入刚刚创建的给我数据action creator。

然后,从mapDispatchToProps中删除所有的代码,换成giveMeDataActionCreator的映射

最后一步,在componentDidMount中,我们删掉伪代码,真正执行action的分发。

保存代码,运行网站。网站打开没问题,能够正常取得数据,这就说明我们的中间件已经发挥作用了,现在所有的数据都是通过store异步处理得到的。
点击查看更多内容
0人点赞

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

评论

作者其他优质文章

正在加载中
Web前端工程师
手记
粉丝
0
获赞与收藏
0

关注TA,一起探索更多经验知识

同主题相似文章浏览排行榜

风间影月说签约讲师

50篇手记,涉及Java、MySQL、Redis、Spring等方向

进入讨论

Tony Bai 说签约讲师

146篇手记,涉及Go、C、Java、Python等方向

进入讨论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消