TypeScript
Кастомный React-хук useFetch
Загрузка данных с состояниями loading/error, отменой запроса при размонтировании и строгими типами.
Код
import { useCallback, useEffect, useState } from 'react';
interface State<T> {
data: T | null;
loading: boolean;
error: Error | null;
}
export function useFetch<T>(url: string, options?: RequestInit) {
const [state, setState] = useState<State<T>>({
data: null, loading: true, error: null,
});
const load = useCallback(
async (signal: AbortSignal) => {
setState((s) => ({ ...s, loading: true, error: null }));
try {
const response = await fetch(url, { ...options, signal });
if (!response.ok) throw new Error(`HTTP ${response.status}`);
setState({ data: (await response.json()) as T, loading: false, error: null });
} catch (error) {
if ((error as Error).name === 'AbortError') return;
setState({ data: null, loading: false, error: error as Error });
}
},
[url],
);
useEffect(() => {
const controller = new AbortController();
void load(controller.signal);
return () => controller.abort(); // отмена при размонтировании
}, [load]);
return state;
}
// const { data, loading, error } = useFetch<User[]>('/api/users/');