React hook for data fetching with loading and error states
1import { useState, useEffect } from 'react';
2
3interface UseFetchResult<T> {
4 data: T | null;
5 loading: boolean;
6 error: Error | null;
7 refetch: () => void;
8}
9
10function useFetch<T>(url: string): UseFetchResult<T> {
11 const [data, setData] = useState<T | null>(null);
12 const [loading, setLoading] = useState(true);
13 const [error, setError] = useState<Error | null>(null);
14 const [refetchIndex, setRefetchIndex] = useState(0);
15
16 useEffect(() => {
17 const fetchData = async () => {
18 try {
19 setLoading(true);
20 const response = await fetch(url);
21
22 if (!response.ok) {
23 throw new Error(`HTTP error! status: ${response.status}`);
24 }
25
26 const json = await response.json();
27 setData(json);
28 setError(null);
29 } catch (e) {
30 setError(e as Error);
31 } finally {
32 setLoading(false);
33 }
34 };
35
36 fetchData();
37 }, [url, refetchIndex]);
38
39 const refetch = () => setRefetchIndex(prev => prev + 1);
40
41 return { data, loading, error, refetch };
42}
43
44// Usage example
45function UserProfile({ userId }: { userId: string }) {
46 const { data, loading, error, refetch } = useFetch<User>(
47 `/api/users/${userId}`
48 );
49
50 if (loading) return <p>Loading...</p>;
51 if (error) return <p>Error: {error.message}</p>;
52 if (!data) return null;
53
54 return (
55 <div>
56 <h1>{data.name}</h1>
57 <button onClick={refetch}>Refresh</button>
58 </div>
59 );
60}Organize your team's code snippets with Snippetly. Share knowledge and boost productivity across your organization.