Skip to content

Instantly share code, notes, and snippets.

@KrofDrakula
Last active December 6, 2023 19:18
Show Gist options
  • Save KrofDrakula/6410b2faa26e0a6bc26e182b4f80213c to your computer and use it in GitHub Desktop.
Save KrofDrakula/6410b2faa26e0a6bc26e182b4f80213c to your computer and use it in GitHub Desktop.
An abortable React hook for making simple GET requests
import { useCallback, useEffect, useState } from 'react'
type UrlInput = Parameters<typeof fetch>[0]
type Overrides = {
fetch?: typeof fetch
onError?: (arg: unknown) => void
}
export const useRequest = <T>(url: UrlInput, overrides?: Overrides) => {
const usedFetch = overrides?.fetch ?? fetch
const usedLogger = overrides?.onError ?? console.error.bind(console)
const [isLoading, setIsLoading] = useState(false)
const [data, setData] = useState<T | undefined>(undefined)
const refresh = (target: UrlInput, abortSignal?: AbortSignal) => {
setIsLoading(true)
usedFetch(target, {
signal: abortSignal,
})
.then((response) => response.json())
.then((incomingData) => setData(incomingData))
.catch((err) => {
usedLogger(err)
setData(undefined)
})
.finally(() => setIsLoading(false))
}
useEffect(() => {
const controller = new AbortController()
refresh(url, controller.signal)
return () => controller.abort()
}, [url.toString()])
const refetch = useCallback(() => {
refresh(url)
}, [url])
return { refresh: refetch, isLoading, data }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment