interface UseFetchRetryProps<T> {
url: string;
options?: RequestInit;
maxRetries?: number;
}
function useFetchRetry<T>({
url,
options,
maxRetries = 3
}: UseFetchRetryProps<T>) {
const [data, setData] = useState<T | null>(null);
const [error, setError] = useState<Error | null>(null);
const [loading, setLoading] = useState(false);
const retryCountRef = useRef(0);
const fetchWithRetry = useCallback(async () => {
setLoading(true);
setError(null);
try {
const response = await retry(
() => fetch(url, options),
maxRetries
);
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const result = await response.json();
setData(result);
} catch (e) {
setError(e as Error);
} finally {
setLoading(false);
retryCountRef.current = 0;
}
}, [url, options, maxRetries]);
return {
data,
error,
loading,
retryCount: retryCountRef.current,
fetch: fetchWithRetry
};
}