A generic data fetching hook with loading and error states.
import { useState, useEffect } from class=class="text-emerald-400">"text-emerald-400">'react'
interface FetchState<T> {
data: T | null
loading: boolean
error: string | null
}
function useFetch<T>(url: string): FetchState<T> {
const [state, setState] = useState<FetchState<T>>({
data: null, loading: true, error: null
})
useEffect(() => {
const controller = new AbortController()
setState({ data: null, loading: true, error: null })
fetch(url, { signal: controller.signal })
.then(res => res.json())
.then(data => setState({ data, loading: false, error: null }))
.catch(err => {
if (err.name !== class=class="text-emerald-400">"text-emerald-400">'AbortError') {
setState({ data: null, loading: false, error: err.message })
}
})
return () => controller.abort()
}, [url])
return state
}
export default useFetchCall with any URL: const { data, loading, error } = useFetch<User[]>('/api/users'). It handles loading states and aborts previous requests on URL change.
Let's discuss how we can bring your idea to life. From initial concept to production-ready product — we've got you covered.