- useApiRequest 新增 loading 状态,execute 自动管理 loading 生命周期 - usePaginatedData 支持泛型筛选参数 (filters: F),函数重载保持旧签名兼容 - 新增 filters/setFilters 状态,fetchFn 调用时传入当前 filters - 向后兼容:旧调用点无需修改
42 lines
1.1 KiB
TypeScript
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 };
|
|
}
|