request 请求插件
Umi4内置了一个request插件用于请求数据,它实际上是基于axios封装了,沿用了大部分axios配置的基础上还封装了一些便于我们使用的接口,此外request插件还封装了ahooks的useRequest()函数,能够简化React组件请求数据的代码。
因此,使用UmiJS框架时推荐直接用request插件来处理请求,这篇笔记我们简单学习一下。
开启和配置request插件
使用内置插件时,我们需要先安装@umijs/plugins。
npm install --save-dev @umijs/plugins
然后在config/config.ts中配置plugins字段和对应的插件配置字段即可。
export default defineConfig({
plugins: ['@umijs/plugins/dist/request'],
request: {
dataField: 'data'
}
});
注意这里request有一个dataField配置,它代表我们后端接口返回JSON中实际的数据字段,例如后端接口返回的整体JSON结构如下:
{
code: 1,
msg: "success",
data: {
studentId: 3,
studentName: "汤姆",
}
}
配置dataField: 'data'后,request插件就会自动取出JSON返回值中的data字段。
使用request请求数据
我们知道axios的基本用法是axios(url, config),request也是request(url, config)。request本身其实是axios的封装,因此使用方法基本一致,这里就不过多展开介绍了。
下面例子我们使用request发起一个GET请求。
service.ts
import {request} from "umi";
export async function getStudentById(params: { id: number }) {
return await request('/api/v1/student', {
method: 'get',
params
});
}
如果你的IDE没有识别到插件的API,在确认config/config.ts中开启了request插件的前提下,可以重新执行npm run setup更新.umi临时文件夹。
请求拦截器
我们知道axios本身还有一些拦截器之类的配置,可以实现日志、错误处理等功能。UmiJS的request也具有类似的API。前面介绍过,UmiJS的src/app.ts中可以对内置插件编写运行时配置,其中的配置会自动加载到浏览器运行,request插件的运行时配置也可以写在这里,下面是一个例子。
src/app.ts
import type {RequestConfig} from 'umi';
interface Response {
code?: number;
msg?: string;
data: any;
success: boolean;
}
export const request: RequestConfig = {
requestInterceptors: [
(config: any) => {
console.log("request", config);
return config;
}
],
responseInterceptors: [
(response) => {
const data = response.data as Response;
if (data.code !== 0) {
console.log("service error", data.msg)
} else {
console.log("response", response);
}
return response;
}
]
};
代码中,requestInterceptors属性配置的是请求拦截器,responseInterceptors配置的是响应拦截器。例子代码中我们仅仅是打印了请求和响应信息,没有实际意义,实际开发中我们可以根据自己的业务需求设置响应的处理逻辑。
使用useRequest()
UmiJS的request插件集成了ahooks库(也是阿里开源的)的useRequest()函数,它封装了很多实用的逻辑比如:自动触发或是手动触发、判断是否加载中等。使用useRequest()函数能够简化React组件中调用请求的逻辑代码编写。
import {request} from "umi";
export async function getStudentById(params: { id: number }) {
return await request('/api/v1/student', {
method: 'get',
params
});
}
import {useRequest} from "umi";
import {getStudentById} from "@/service/service";
export default function HomePage() {
const {data, loading} = useRequest(() => {
return getStudentById({id: 1});
});
return (
<div>
{loading ? '加载中' : JSON.stringify(data)}
</div>
);
}
上面代码中,我们通过解构赋值获取了data和loading字段,前者是接口返回的数据,后者是一个状态字段用于判断接口是否正在请求中。
默认情况下,useRequest()是自动执行的,但也可以实现手动触发。下面是一个例子。
import {useRequest} from "umi";
import {getStudentById} from "@/service/service";
export default function HomePage() {
const {data, loading, run} = useRequest(() => {
return getStudentById({id: 1});
}, {manual: true});
return (
<div>
<button onClick={run}>点我加载数据</button>
{loading ? '加载中' : JSON.stringify(data)}
</div>
);
}
useRequest()的第2个参数实际上是个配置块。代码中,我们对useRequest()配置manual: true,这样它就不会自动执行而是需要我们手动触发,我们使用解构赋值获取了run属性,它是一个用于触发useRequest()执行的函数,点击按钮时调用run()函数即可实现手动触发。
useRequest()实际上还有很多其它用法,比如防抖、限流、轮询等,这里就不多介绍了,具体可以参考相关文档。