useFetch — Generic Data Fetching Hook
Custom React hook for data fetching with loading, error, and refetch states using the Fetch API.
import { useState, useEffect, useCallback } from 'react';
interface UseFetchResult<T> {
data: T | null;
error: string | null;
loading: boolean;
refetch: () => void;
}
export function useFetch<T>(url: string): UseFetchResult<T> {
const [data, setData] = useState<T | null>(null);
const [error, setError] = useState<string | null>(null);
const [loading, setLoading] = useState(true);
const fetchData = useCallback(() => {
let cancelled = false;
setLoading(true);
setError(null);
fetch(url)
.then((res) => {
if (!res.ok) throw new Error(`HTTP ${res.status}`);
return res.json();
})
.then((json) => {
if (!cancelled) setData(json as T);
})
.catch((err) => {
if (!cancelled) setError(err.message);
})
.finally(() => {
if (!cancelled) setLoading(false);
});
return () => { cancelled = true; };
}, [url]);
useEffect(() => {
const cleanup = fetchData();
return cleanup;
}, [fetchData]);
return { data, error, loading, refetch: fetchData };
}
// Usage:
// const { data, loading, error } = useFetch<User[]>('/api/users');Use Cases
- API data fetching
- Dashboard widgets
- Client-side data loading
Tags
Related Snippets
Similar patterns you can reuse in the same workflow.
useDebounce — Debounced Value Hook
Debounce any rapidly-changing value with a configurable delay. Useful for search inputs and resize handlers.
useLocalStorage — Persistent State Hook
Sync React state with localStorage including SSR safety, JSON serialization, and cross-tab updates.
useClickOutside — Outside Click Detection
Detect clicks outside a referenced element to close dropdowns, modals, and popover menus.
useMediaQuery — Responsive Breakpoint Hook
Subscribe to CSS media query changes and get a boolean flag for responsive rendering logic in React.