Skip to content

Instantly share code, notes, and snippets.

@sametcn99
Created November 4, 2024 13:29
Show Gist options
  • Select an option

  • Save sametcn99/6674f3fadd43006ddf893553188087fc to your computer and use it in GitHub Desktop.

Select an option

Save sametcn99/6674f3fadd43006ddf893553188087fc to your computer and use it in GitHub Desktop.
react usefetch hook
import { useState, useEffect, useMemo } from 'react'
type FetchOptions = RequestInit
type FetchResult<T> = {
data: T | null
loading: boolean
error: string | null
}
const useFetch = <T = unknown,>(
url: string,
options?: FetchOptions
): FetchResult<T> => {
const [data, setData] = useState<T | null>(null)
const [loading, setLoading] = useState(true)
const [error, setError] = useState<string | null>(null)
const memoizedOptions = useMemo(() => options, [options])
useEffect(() => {
const controller = new AbortController()
const { signal } = controller
const fetchData = async () => {
setLoading(true)
setError(null)
try {
const response = await fetch(url, { ...memoizedOptions, signal })
if (!response.ok) {
throw new Error(`Network response was not ok: ${response.statusText}`)
}
const result: T = await response.json()
setData(result)
} catch (err) {
if (err !== 'AbortError') {
const error = err as Error
setError(error.message)
}
} finally {
setLoading(false)
}
}
fetchData()
return () => {
controller.abort()
}
}, [url, memoizedOptions])
return { data, loading, error }
}
export default useFetch
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment