014 Umi 中的 fetch 与 ahooks useRequest 的梦幻联动

简介: 014 Umi 中的 fetch 与 ahooks useRequest 的梦幻联动

image.png



request 请求数据

Umi@4 中使用 axios 代替了 fetch,有一些使用上的差异,这节课我们提到的是 Umi 中的 fetch 方案


前面我们花了大量的篇幅介绍项目中的数据流方案,其实他们是作为数据消费部分存在的。但是我们并没有真正的发起数据请求,在这里我们将详细的介绍在 umi 中如何规范的发起数据请求,即如何将数据传入我们之前介绍的数据流方案中。


在很多其他项目中,我们都会单独维护一个 http 请求的工具类,它一般会在你的 utils 文件夹中,但是通过多个项目的代码比对,我们发现这个工具类有至少80%的代码是重复的,且不同人员的维护上也比较随意,代码维护上是比较乱的。因此我们将 request 请求内置到框架中。


import { request } from 'umi';
const data = await request('/api/hello', {
  method: 'get',
});
复制代码


直接使用,对服务端的返回数据模型,会有一些约定

如果你的服务端返回数据格式不同,会在后面的配置中提到如何处理这种情况。

interface ErrorInfoStructure {
  success: boolean; // if request is success
  data?: any; // response data
  ...
}
复制代码


一般我们对服务端发起请求,最常见的会涉及到,统一的请求url、统一的head、默认的请求方式(默认 get或者默认post)等。

这些内容,我们都在运行时配置中提供了修改方式。


运行时配置顾名思义就是在项目运行时会根据一些条件或者时机来修改配置,常常用于某些需要动态配置的情况。在前面讲解 umi 中的配置时我们已经提过运行时配置。记住运行时配置只有一个地方 src/app.ts。某些功能会用到它。你需要按约定导出对象,不能导出不存在的对象。这些对象由你所使用的插件定义,包括内置插件和外部引用插件。


export const request = {
  prefix: '',
  method: 'get',
  errorConfig: {
    adaptor: (resData) => {
      return {
        ...resData,
        success: resData.ok,
        errorMessage: resData.message,
      };
    },
  },
};
复制代码

在运行时配置中导出 request 是我们的请求功能要求的。



request 配置

参数 说明 类型 可选值 默认值
method 请求方式 string get , post , put ... get
params url 请求参数 object 或 URLSearchParams 对象 -- --
data 提交的数据 any -- --
headers fetch 原有参数 object -- {}
timeout 超时时长, 默认毫秒, 写操作慎用 number -- --
prefix 前缀, 一般用于覆盖统一设置的 prefix string -- --
suffix 后缀, 比如某些场景 api 需要统一加 .json string -- --
credentials fetch 请求包含 cookies 信息 string -- credentials: 'same-origin'
useCache 是否使用缓存(仅支持浏览器客户端) boolean -- false
validateCache 缓存策略函数 (url, options) => boolean -- 默认 get 请求做缓存
ttl 缓存时长, 0 为不过期 number -- 60000
maxCache 最大缓存数 number -- 无限
requestType post 请求时数据类型 string json , form json
parseResponse 是否对 response 做处理简化 boolean -- true
charset 字符集 string utf8 , gbk utf8
responseType 如何解析返回的数据 string json , text , blob , formData ... json , text
throwErrIfParseFail 当 responseType 为 'json', 对请求结果做 JSON.parse 出错时是否抛出异常 boolean -- false
getResponse 是否获取源 response, 返回结果将包裹一层 boolean -- fasle
errorHandler 异常处理, 或者覆盖统一的异常处理 function(error) --
cancelToken 取消请求的 Token CancelToken.token -- --

fetch 原其他参数有效, 详见fetch 文档


上面列出的是 request 支持的所有配置,看起来有些复杂,但是我们在实际使用中最经常修改的,其实只有 prefix,当你需要切换请求前缀时,会比较频繁的修改它。其他的数据应该是在首次接口连调的时候,和服务端约定好的配置。



修改请求数据-加密或过滤

一般我们还有有一个常用的需求,对我们发出的数据进行安全性的数据加密。或者仅针对某个接口对数据进行过滤。


这时候就能用到我们的中间件功能了。这个在 express 项目中是很容易理解的概念。

const middleware = async (ctx, next) => {
  // 这里是对请求数据的操作,比如加密或者过滤数据,我们可以在这里操作
  // url 请求不包含 ‘abc’ 时,就做某些操作
  if (!ctx.req.url.includes('abc')) {
  }
  await next();
  // next 执行之后,这部分我们一般是对请求结果做操作,比如统一的错误码处理,或者token失效这些,都可以在这里处理
  // 以下代码只是模拟,正式的写法要根据服务端的约定
  if (ctx.res.errors) {
    const {
      errorCode,
      fieldPath,
      message,
      value } = ctx.res.errors[0];
    if (errorCode === '0000') {
      gotoLogin(message);
    } else {
      Toast.fail(`${message}` || '请求异常请稍后重试', 1);
    }
  }
};
export const request = {
  prefix: '', // 统一的请求头
  middlewares: [middleware],
  errorHandler: (error: ResponseError) => {
    // 集中处理错误
    console.log(error);
  },
};
复制代码



ahooks useRequest

理解了上面的概念,那么在我们之前提到的数据流中,应该在什么时机发起请求呢? 一般我们会在 useEffect 中,请求服务端接口,但是为了更加简洁的使用 request,我们引入了 ahooks 中的 useRequest。 这里我们只介绍两种最常见的用法


默认用法

默认用法最好理解,常常用来加载页面的初始化数据。比如列表的首屏展示。

import { useRequest } from 'umi';
import Mock from 'mockjs';
import React from 'react';
function getUsername(): Promise<string> {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve(Mock.mock('@name'));
    }, 1000);
  });
}
export default () => {
  const { data, error, loading } = useRequest(getUsername);
  if (error) {
    return <div>failed to load</div>;
  }
  if (loading) {
    return <div>loading...</div>;
  }
  return <div>Username: {data}</div>;
};
复制代码


值得注意的是,上面的代码看起来像是同步执行的,但其实 react 的 hooks 都是异步的,简单理解就是,数据修改时都会导致页面重绘,所以当你的自定义 hooks 很多的时候,可能你的页面会渲染好几次。


手动触发

如果设置了 options.manual = true,则 useRequest 不会默认执行,可以在合适的时候通过 run 来触发执行。比如常见的搜索查询,我们会在输入完条件之后,点击查询按钮才会调用服务端接口。


import { message } from 'antd';
import React, { useState } from 'react';
import { useRequest } from 'umi';
function changeUsername(username: string): Promise<{ success: boolean }> {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve({ success: true });
    }, 1000);
  });
}
export default () => {
  const [state, setState] = useState('');
  const { loading, run } = useRequest(changeUsername, {
    manual: true,
    onSuccess: (result, params) => {
      if (result.success) {
        setState('');
        message.success(`The username was changed to "${params[0]}" !`);
      }
    },
  });
  return (
    <div>
      <input
        onChange={(e) => setState(e.target.value)}
        value={state}
        placeholder="Please enter username"
        style={{ width: 240, marginRight: 16 }}
      />
      <button disabled={loading} type="button" onClick={() => run(state)}>
        {loading ? 'Loading' : 'Edit'}
      </button>
    </div>
  );
};
复制代码


感谢阅读,这个文章仅仅作为这个概念的讲解,实战在后续课程中,因此这节课没有源码归档。你不需要修改任何的文件。

目录
相关文章
|
3月前
|
JavaScript 前端开发 测试技术
Vue.js开发者必看!Vue Test Utils携手端到端测试,打造无懈可击的应用体验,引领前端测试新风尚!
【8月更文挑战第30天】随着Vue.js的普及,构建可靠的Vue应用至关重要。测试不仅能确保应用质量,还能提升开发效率。Vue Test Utils作为官方测试库,方便进行单元测试,而结合端到端(E2E)测试,则能构建全面的测试体系,保障应用稳定性。本文将带你深入了解如何使用Vue Test Utils进行单元测试,通过具体示例展示如何测试组件行为;并通过Cypress进行E2E测试,确保整个应用流程的正确性。无论是单元测试还是E2E测试,都能显著提高Vue应用的质量,让你更加自信地交付高质量的应用。
76 0
|
4月前
|
JavaScript Java 测试技术
基于springboot+vue.js+uniapp的农业信息智能化种植系统附带文章源码部署视频讲解等
基于springboot+vue.js+uniapp的农业信息智能化种植系统附带文章源码部署视频讲解等
74 0
|
6月前
|
JavaScript Java 测试技术
基于ssm+vue.js的模具制造企业订单跟踪管理系统附带文章和源代码设计说明文档ppt
基于ssm+vue.js的模具制造企业订单跟踪管理系统附带文章和源代码设计说明文档ppt
40 2
|
6月前
|
JavaScript Java 测试技术
基于springboot+vue.js的中山社区医疗综合服务平台附带文章和源代码设计说明文档ppt
基于springboot+vue.js的中山社区医疗综合服务平台附带文章和源代码设计说明文档ppt
25 0
基于springboot+vue.js的中山社区医疗综合服务平台附带文章和源代码设计说明文档ppt
|
5月前
|
JavaScript Java 测试技术
基于ssm+vue.js+uniapp小程序的果蔬种植销售一体化服务平台附带文章和源代码部署视频讲解等
基于ssm+vue.js+uniapp小程序的果蔬种植销售一体化服务平台附带文章和源代码部署视频讲解等
31 0
|
5月前
|
JavaScript Java 测试技术
基于ssm+vue.js+uniapp小程序的智能实时疫情监管服务平台附带文章和源代码部署视频讲解等
基于ssm+vue.js+uniapp小程序的智能实时疫情监管服务平台附带文章和源代码部署视频讲解等
24 0
|
6月前
|
JavaScript Java 测试技术
基于ssm+vue.js的深加工农产品推广服务平台附带文章和源代码设计说明文档ppt
基于ssm+vue.js的深加工农产品推广服务平台附带文章和源代码设计说明文档ppt
26 0
|
6月前
|
JavaScript Java 测试技术
基于springboot+vue.js的制造装备物联及生产管理ERP系统附带文章和源代码设计说明文档ppt
基于springboot+vue.js的制造装备物联及生产管理ERP系统附带文章和源代码设计说明文档ppt
50 0
|
6月前
|
JavaScript Java 测试技术
基于SpringBoot+Vue+uniapp的智能实时疫情监管服务平台的详细设计和实现(源码+lw+部署文档+讲解等)
基于SpringBoot+Vue+uniapp的智能实时疫情监管服务平台的详细设计和实现(源码+lw+部署文档+讲解等)
|
6月前
|
JavaScript Java 测试技术
基于ssm+vue.js的新能源汽车在线租赁管理系统附带文章和源代码设计说明文档ppt
基于ssm+vue.js的新能源汽车在线租赁管理系统附带文章和源代码设计说明文档ppt
44 0