loading 动画 放在请求拦截里做统一处理,还是放在每个页面里

关于loading 动画,目前有两种方案:
1、放在请求拦截里,每次发起请求,都展示loading 动画。
优:这样做的好处是不用每次都写loading 的开与关

2、放在页面里,对每次请求处理(单个或多个请求)做loading 的开与关。
缺:每个页面或请求里都得写loading 的开关逻辑,很繁琐。

以上为个人观点,欢迎大家讨论与补充。

最佳答案

其实就是逻辑统一处理,还是每个页面单独处理的区别。

简单聊聊我所知道的几种不同方案

image.png

一、在请求接口时拦截,例如axios的拦截器

这个方案就是题主说的第一种方案。这种方案如果结合vue或者react中使用,那么我们必须要思考的一个问题是,这个loading是代表的那种loading。

很显然,一定得是全局loading,否则很多细节无法处理,例如如果有多个接口同时请求怎么办?因此,要把这种方案实施下来,就需要

  1. Loading组件独立于所有页面组件,是公用的全局组件
  2. 多个请求时,需要计算正在请求的个数

如果从代码量考虑,这样的方式确实减少了工作量,但是缺陷也很明显,缺乏灵活性。只要有接口请求,就只能把这个全局Loading抬出来。很多场景无法适应。

当然,如果是后台管理系统,不需要Loading具有太多的灵活性,是可以这样处理的。就看你能不能说服团队其他所有人,这个项目,所有的加载情况都这样处理。

二、在组件中拦截,例如ant design pro中使用的dva-loading

dva-loading是react-redux解决方案中的中间件。dva-loading在全局store中维护了一个EffectLoading的对象,所有loading的状态请求都放在了该对象中,并且每个请求根据namespace的不同都有对应的唯一值。也就是说,这种方式避免了整个全局中有一个loading,而是把所有的loading状态各自有一个唯一的标识能够访问得到。

// EffectLoading
{
  effects: {
    'login/fetch': true,
    'login/user': true,
    'dashboard/fetch': false,
    'dashboard/list': false,
  },
  global: false,
  models: {
    'login/fetch': true,
    'login/user': true,
  }
}

这种方式也是统一处理,但是处理的方式和第一种方式不一样,这种方式更具灵活性,我们可以在组件里针对自己当前组件的状态进行不同的处理。该方式仅仅只是把对应请求的loading传入组件,在组件中如何处理,则自己决定。

这种方式由于第一种方式,当然两种方式的处理思维也可以结合起来,糅合成更合理的方案

但是这样的方案在react中也并非没有缺陷。

dva-loading让整个项目全局共享一个loadingEffect对象。

也就是说,无论你的组件如何划分,loading都不可避免的成为了共享状态。可是在很多情况下,我们仅仅只希望loading成为当前页面或者某个子组件的私有状态。因此dva-loading虽然看上去简化了写法,却让组件化思维固化,失去了灵活性。

也正因为处于最顶层的共享数据,当loadingEffect状态改变时,会导致额外的冗余渲染。因此,dva-loading应该慎用。

三、每个组件,每个请求维护自己的loading状态

当然,这样的方式灵活性都很好,无论交互想要怎么处理,都可以完美解决。缺点也很明显,完美要额外定义很多loading状态,维护成本会稍高,代码也会多些一点。

四、在react中,利用自定义hooks

这是目前我认知到的最完美的方案。

超性感的的react hooks(五):自定义hooks中我跟大家介绍了如何使用自定义hooks。
并在使用hooks重构antd pro的想象力(三)我是如何利用hooks干掉redux的中介绍了如何自定义一个能够处理请求的hooks。

首先我们定义一个全局的能够处理请求的自定义hooks useInitial

【详细代码见上述文章】

在组件中使用时,只需要如下一句代码即可拿到对应请求的loading状态和请求数据

const {loading, data} = useInitial(api);

该方案是将请求逻辑统一封装成为自定义hooks,极大降低了维护成本,并且每个loading都相互独立,互不影响,灵活性也不存在任何问题。

因此我认为这是最完美的解决方案。不过要基于react hooks。

五、选择最适合自己的方案

结合自己团队和项目的情况,选择最适合自己的方案,才是最好的方案!