在日常开发过程中我们采用react+redux方案进行开发,往往会遇到redux样板代码过多的问题,在不断的抽离过程中,顺手封装了一个redux-middleware。在此进行详细的问题和解决思路。最终代码和示例可以再项目中查看并使用,欢迎使用、建议并star~
抛出问题
使用Redux进行开发时,遇到请求,我们往往需要很复杂的过程,并且这个过程是重复的。我们往往会把一个请求拆分成三个阶段,对应到三个Action Type中去,并且配合redux-thunk中间件,将一个异步action进行拆分,分别对应请求的三个阶段。如下所示:
|
|
同时,我们需要在reducer中,添加三个action所对应的状态更改,来相应的对整个请求进行展示。例如:
- 开始请求时进行loading, 需要loading字段
- 请求成功时结束loading, 修改data
- 请求失败时结束loading, 展示error
对应我们需要写以下内容:
|
|
针对一个完整健壮的请求,我们往往需要把上述的代码全部写一遍。假设我们一个页面有N个请求接口,我们需要把这些近似相同的代码书写无数遍,显然是很麻烦又不太好的做法,那么我们如何在保证代码流程和可读性的同时,来减少样板代码呢
初步解决方案,使用函数把它封装起来
其实针对这种重复代码,我们第一个想到的就是把它封装成一个函数,将可变因素作为一个参数即可。
但是这个可能稍微复杂一点,因为针对这个函数,我们可能会进行几个不太相关的步骤,或者不能说是步骤,应该说是拿到不懂的我们想要的内容:
- 获取三个状态的action
- 在请求过程中,分别对三个action进行处理,并且可灵活配置请求参数,请求结果,错误处理等
- 自定义initialState,并且在reducer自动对应三个action状态,更新state
由于这个不是我们最终的方案,我直接将代码放出来,阐明我们基本的思路:
|
|
通过这个工具函数,我们可以极大的简化整个流程,针对一个请求,我们可以通过以下方式进行:
|
|
在reducer中,我们可以直接使用reducerCreator创建reducer, 并且可以添加额外的内容
|
|
通过这种方式,我们极大的减少了整个过程的代码,并且可以在每个过程中灵活的加入我们想要的东西。
配合我封装的react组件中的Box组件,很方便的实现
请求->loading->展现内容的过程。
但是,总是隐约觉得这个代码有些不舒服,不舒服在哪儿呢?
没错,虽然它很大程度的简化了代码,但是使用这个工具函数后,极大的改变了整个redux代码的结构,
整个函数使用过程及语义化十分不明显,我们很难一眼看出来我们都做了什么。
并且,不熟悉Api的人用起来会十分难受。
因此,我们对以上代码进行改善,以达到我们最终的要求:优雅
引子
Redux借鉴Koa的中间件机制,也给我们提供了一个很好的middleware使用。具体的原理我们在此不进行赘述,我们来看下一个基础的middleware长什么样子:
|
|
我们会看到,在一个middleware中,我们可以拿到store和action, 并且自动的执行下一个中间件或者action。
基本获取了我们所有需要的内容,我们可以直接在将请求过程中的固定代码,交给middleware来做!
使用redux-middleware简化流程
我们可以将分发action的过程在此自动进行,相信很多人都会这么做,我们只需要定义我们的特殊action的格式,并且针对此action进行特殊处理即可。比如我们定义我们的请求action为这样:
|
|
在middleware中,我们可以进行以下处理:
|
|
同时,我们提供actionCreator, reducerCreator来创建对应的action, 和reducer。保证流程和结构不变的情况下,简化代码。
最终版本
- apply middleware
|
|
- actions
|
|
- reducer
|
|
##总结
从开始的问题抛出到解决思路到不断完善的过程,是解决问题的标准流程。通过这次封装,我们很好的解决了日常开发过程中Redux请求代码冗余的问题,并且也充分的了解了redux-middleware的机制。欢迎指正且star~