Files
hms/apps/web/src/hooks/useApiRequest.ts
iven fdceed7284 feat(web): useApiRequest 添加 loading + usePaginatedData 泛型筛选
- useApiRequest 新增 loading 状态,execute 自动管理 loading 生命周期
- usePaginatedData 支持泛型筛选参数 (filters: F),函数重载保持旧签名兼容
- 新增 filters/setFilters 状态,fetchFn 调用时传入当前 filters
- 向后兼容:旧调用点无需修改
2026-04-27 20:26:00 +08:00

42 lines
1.1 KiB
TypeScript

import { useCallback, useState } from 'react';
import { message } from 'antd';
function extractErrorMessage(err: unknown): string {
if (err && typeof err === 'object' && 'response' in err) {
const resp = (err as { response?: { data?: { message?: string } } }).response;
return resp?.data?.message || '';
}
if (err instanceof Error) return err.message;
return '';
}
interface UseApiRequestReturn {
execute: <T>(fn: () => Promise<T>, successMsg?: string, errorMsg?: string) => Promise<T | null>;
loading: boolean;
}
export function useApiRequest(): UseApiRequestReturn {
const [loading, setLoading] = useState(false);
const execute = useCallback(async <T>(
fn: () => Promise<T>,
successMsg?: string,
errorMsg = '操作失败',
): Promise<T | null> => {
setLoading(true);
try {
const result = await fn();
if (successMsg) message.success(successMsg);
return result;
} catch (err) {
const msg = extractErrorMessage(err);
message.error(msg || errorMsg);
return null;
} finally {
setLoading(false);
}
}, []);
return { execute, loading };
}