typescriptadvanced
useFetch with Cache Hook
Data fetching hook with built-in cache, loading, error states, and automatic revalidation.
typescriptPress ⌘/Ctrl + Shift + C to copy
import { useState, useEffect, useRef } from 'react';
const cache = new Map<string, { data: unknown; timestamp: number }>();
interface UseFetchOptions {
cacheTime?: number;
revalidateOnFocus?: boolean;
}
export function useFetch<T>(url: string, options: UseFetchOptions = {}) {
const { cacheTime = 60_000, revalidateOnFocus = true } = options;
const [data, setData] = useState<T | null>(null);
const [error, setError] = useState<Error | null>(null);
const [loading, setLoading] = useState(true);
const abortRef = useRef<AbortController>();
const fetchData = async () => {
const cached = cache.get(url);
if (cached && Date.now() - cached.timestamp < cacheTime) {
setData(cached.data as T);
setLoading(false);
return;
}
abortRef.current?.abort();
abortRef.current = new AbortController();
try {
setLoading(true);
const res = await fetch(url, { signal: abortRef.current.signal });
if (!res.ok) throw new Error(`HTTP ${res.status}`);
const json = await res.json();
cache.set(url, { data: json, timestamp: Date.now() });
setData(json);
setError(null);
} catch (err) {
if (err instanceof DOMException && err.name === 'AbortError') return;
setError(err instanceof Error ? err : new Error('Fetch failed'));
} finally {
setLoading(false);
}
};
useEffect(() => { fetchData(); return () => abortRef.current?.abort(); }, [url]);
useEffect(() => {
if (!revalidateOnFocus) return;
const onFocus = () => fetchData();
window.addEventListener('focus', onFocus);
return () => window.removeEventListener('focus', onFocus);
}, [url, revalidateOnFocus]);
return { data, error, loading, refetch: fetchData };
}Use Cases
- API data fetching
- Dashboard widgets
Tags
Related Snippets
Similar patterns you can reuse in the same workflow.
typescriptintermediate
useFetch — Generic Data Fetching Hook
Custom React hook for data fetching with loading, error, and refetch states using the Fetch API.
Best for: API data fetching
#hooks#fetch
typescriptintermediate
React Custom Hook for Data Fetching
A reusable useFetch hook with loading states, error handling, caching, and abort support.
Best for: Reusable data fetching across components
#react#hooks
typescriptintermediate
useAsync Hook for Promise Management
Manage async operations with loading, error, and data states using a reusable hook pattern.
Best for: Data fetching with status tracking
#react#hooks
typescriptbeginner
useAbortController Hook
Creates and manages AbortController instances for cancelling fetch requests on unmount.
Best for: Cancelling stale requests
#hooks#abort