async
useFetch
Encapsulates fetch logic with loading, data, and error states. Automatically cancels the request if the component unmounts.
useFetch.ts
import { useState, useEffect } from "react"
interface FetchState<T> {
data: T | null
loading: boolean
error: string | null
}
export function useFetch<T>(url: string): FetchState<T> {
const [state, setState] = useState<FetchState<T>>({
data: null,
loading: true,
error: null,
})
useEffect(() => {
let cancelled = false
setState({ data: null, loading: true, error: null })
fetch(url)
.then((res) => {
if (!res.ok) throw new Error(`HTTP ${res.status}`)
return res.json() as Promise<T>
})
.then((data) => {
if (!cancelled) setState({ data, loading: false, error: null })
})
.catch((err: Error) => {
if (!cancelled) setState({ data: null, loading: false, error: err.message })
})
return () => { cancelled = true }
}, [url])
return state
}Was this helpful?
Sign in to give feedback
