useFuncRequest Hook 文档
概述
useFuncRequest 是一个强大的 React Hook,用于优雅地管理异步函数调用。它提供了加载状态跟踪、错误处理、取消请求和生命周期回调等完整功能。
核心特性
- ✅ 自动加载状态管理
- ✅ 请求取消支持(AbortController)
- ✅ 完善的错误处理机制
- ✅ 灵活的生命周期回调
- ✅ 自动执行选项
- ✅ TypeScript 强类型支持
基本用法
import { useFuncRequest } from './useFuncRequest';
async function fetchUser(id: string) {
const response = await fetch(`/api/users/${id}`);
return response.json();
}
function UserProfile({ userId }) {
const { data, loading, error } = useFuncRequest(fetchUser, {
autoRunArgs: [userId], // 自动执行
onSuccess: user => console.log('用户数据:', user),
onError: err => console.error('加载失败:', err),
});
if (loading) return <div>加载中...</div>;
if (error) return <div>错误: {error.message}</div>;
return <div>{data?.name}</div>;
}
API 说明
输入参数
| 参数名 |
类型 |
必填 |
描述 |
| asyncFunc |
(...args: any[]) => Promise |
是 |
要包装的异步函数 |
| options |
UseFuncRequestOptions |
否 |
配置选项 |
配置选项 (UseFuncRequestOptions)
| 选项 |
类型 |
描述 |
| autoRunArgs |
Parameters |
自动执行时的参数 |
| onBefore |
(...args: Parameters<T>) => boolean \| Promise<boolean> |
执行前的回调,返回 false 可阻止执行 |
| onSuccess |
(data: UnwrapPromise<ReturnType<T>>) => void Promise<void> |
成功回调 |
| onError |
(error: Error) => void \| Promise<void> |
失败回调 |
| onFinally |
() => void \| Promise<void> |
结束回调(无论成功失败) |
返回值
| 属性 |
类型 |
描述 |
| run |
(...args: Parameters) => Promise>> |
手动触发函数执行 |
| cancel |
() => void |
取消当前请求 |
| loading |
boolean |
加载状态 |
| error |
Error \| null |
错误对象 |
| data |
UnwrapPromise<ReturnType<T>> \| null |
响应数据 |
高级用法
手动触发请求
const { run } = useFuncRequest(fetchUser);
const handleClick = () => {
run('user123').catch(() => {});
};
请求取消
const { run, cancel } = useFuncRequest(longRunningRequest);
// 开始请求
run();
// 取消请求
cancel();
前置条件检查
useFuncRequest(submitForm, {
onBefore: formData => {
if (!formData.valid) {
alert('表单不完整');
return false; // 阻止执行
}
return true;
},
});
自动传递 AbortSignal
async function fetchWithSignal(url: string, { signal }: { signal?: AbortSignal }) {
const response = await fetch(url, { signal });
return response.json();
}
// 自动注入 signal 参数
useFuncRequest(fetchWithSignal);