Last active
November 24, 2023 04:26
-
-
Save intrnl/574b2afea4b7a07425abf501ad2bcad0 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { useState, useEffect } from 'preact/hooks' | |
/** | |
* @param {RequestInfo} url | |
* @param {RequestInit} opts | |
* @returns {useFetchObject} | |
*/ | |
function useFetch (url, opts) { | |
const [response, setResponse] = useState(undefined) | |
const [error, setError] = useState(undefined) | |
const [isFetching, setIsFetching] = useState(true) | |
useEffect(() => { | |
const controller = new AbortController | |
let cancel = false | |
const getResponse = async () => { | |
setResponse(undefined) | |
setError(undefined) | |
setIsFetching(true) | |
try { | |
const resp = await fetch(url, { | |
...opts, | |
signal: controller.signal, | |
}) | |
if (cancel) return | |
if (!resp.ok) throw resp | |
const type = resp.headers.get('content-type') | |
let data | |
if (type && type.includes('application/json')) { | |
data = await resp.json() | |
} else { | |
data = await resp.text() | |
} | |
if (cancel) return | |
setResponse(data) | |
setIsFetching(false) | |
} catch (err) { | |
if (cancel) return | |
setError(err) | |
} | |
} | |
getResponse() | |
return () => { | |
cancel = true | |
controller.abort() | |
} | |
}, [url, opts]) | |
return { | |
response, | |
error, | |
isFetching, | |
} | |
} | |
export default useFetch | |
/** | |
* @typedef {object} useFetchObject | |
* @property {Response} response | |
* @property {Error} error | |
* @property {boolean} isFetching | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment