Ahooks 是阿里巴巴开源的一个高质量的 React Hooks 库,提供了大量实用的自定义 Hooks,可以帮助开发者提高开发效率,减少重复代码。
1.安装
npm install ahooks
2.数据类型及Api接口
调用 useRequest
之前,我们需要先定义数据类型和实现一个简单的api接口
定义数据类型 src\types\user.ts
export interface UserResp {
id: number;
name: string;
}
export interface UserSaveReq {
id: number;
name: string;
}
实现请求接口 src\apis\user.ts
import { http } from '@/server/http';
import { UserResp, UserSaveReq } from '@/types/user';
export class UserApi {
// 获取详情
static get(id: number) {
return http.get<{ id: number }, UserResp>(
'http://demo.com/api.php?sleep=1',
{
id: id,
}
);
}
// 保存用户信息
static save(data: UserSaveReq) {
return http.post<UserSaveReq, UserResp>('http://demo.com/api.php', data);
}
}
3.使用 useRequest 管理异步请求
// src/components/UserList.tsx
import React from 'react';
import { useRequest } from 'ahooks';
import { getUserList } from '../services/userService';
interface User {
id: number;
name: string;
email: string;
}
const UserList: React.FC = () => {
const { data, loading, error } = useRequest(() => UserApi.get(1));
if (loading) return <div>Loading...</div>;
if (error) return <div>Error: {error.message}</div>;
return (
<div>
<p>{data && <p> {JSON.stringify(data)}</p>}</p>
</div>
);
};
export default UserList;
4.使用 Promise.all 组合多个请求
下面的内容实现了自动管理loading,error状态
import useRequest from '@/components/use-request';
import { UserApi } from '@/apis/user';
import { Button } from 'antd';
import { useState } from 'react';
export default function Eg06() {
const [count, setCount] = useState<number>(1);
// 使用 Promise.all 组合多个请求
const { loading, data, run } = useRequest(async () => {
const [one, two] = await Promise.all([UserApi.get(count), UserApi.get(1)]);
return { one, two };
});
return (
<div
style={{
padding: '100px',
border: '1px solid red',
}}
>
<p>计数:{count}</p>
<Button onClick={() => setCount(count + 1)}>增加1</Button>
<Button onClick={run}>查询</Button>
<p>{loading && <p>Loading...</p>}</p>
<p>all: {!loading && JSON.stringify(data?.one.data)}</p>
</div>
);
}
这里实现了代码自动提示

5.使用串行请求(一个请求的结果作为另一个请求的参数)
方法一:使用依赖请求
import useRequest from '@/components/use-request';
import { UserApi } from '@/apis/user';
export default function Eg06() {
// 使用依赖请求(一个请求的结果作为另一个请求的参数)
const { data: first } = useRequest(() => UserApi.get(1));
const { data: second } = useRequest(
() => UserApi.save(first?.data as userSaveReq),
{
// 只有当 first 存在时才执行
ready: !!first,
}
);
return (
<div
style={{
padding: '100px',
border: '1px solid red',
}}
>
<p>依赖请求</p>
<p>first:</p>
<p>{first && <p> {JSON.stringify(first)}</p>}</p>
<p>second:</p>
<p>{second && <p> {JSON.stringify(second)}</p>}</p>
</div>
);
}
方法二:使用 runAsync + then 链式调用
import { useRequest } from 'ahooks';
function Demo() {
// 第一个请求
const { runAsync: runFirstRequest } = useRequest(
(params) => fetchFirstData(params),
{ manual: true } // 手动触发
);
// 第二个请求(依赖第一个请求的结果)
const { run: runSecondRequest } = useRequest(
(secondParams) => fetchSecondData(secondParams),
{ manual: true }
);
const handleClick = async () => {
try {
// 1. 先执行第一个请求
const firstResult = await runFirstRequest({ id: 1 });
// 2. 用第一个请求的结果发起第二个请求
runSecondRequest({ data: firstResult.data });
} catch (error) {
console.error(error);
}
};
return <button onClick={handleClick}>Start Requests</button>;
}
方法三:使用 useRequest 的 onSuccess 回调
import { useRequest } from 'ahooks';
function Demo() {
// 第一个请求
const { run: runFirstRequest } = useRequest(
(params) => fetchFirstData(params),
{
manual: true,
onSuccess: (firstResult) => {
// 当第一个请求成功时,自动发起第二个请求
runSecondRequest({ data: firstResult.data });
}
}
);
// 第二个请求
const { run: runSecondRequest } = useRequest(
(secondParams) => fetchSecondData(secondParams),
{ manual: true }
);
return <button onClick={() => runFirstRequest({ id: 1 })}>Start Requests</button>;
}
方法四:直接嵌套请求(适用于强依赖关系)
import { useRequest } from 'ahooks';
function Demo() {
const { run: runNestedRequest } = useRequest(
async (params) => {
// 1. 先执行第一个请求
const firstResult = await fetchFirstData(params);
// 2. 用第一个结果发起第二个请求
const secondResult = await fetchSecondData({ data: firstResult.data });
// 3. 返回两个请求的结果
return { firstResult, secondResult }
},
{ manual: true }
);
return <button onClick={() => runNestedRequest({ id: 1 })}>Start Requests</button>;
}