Skip to content

Instantly share code, notes, and snippets.

@filevich
Created September 3, 2022 04:04
Show Gist options
  • Save filevich/08c240fe895b0028b5d9564d18d25e0d to your computer and use it in GitHub Desktop.
Save filevich/08c240fe895b0028b5d9564d18d25e0d to your computer and use it in GitHub Desktop.
import { useState, useEffect, useRef, useMemo } from 'react';
export const useQuery = () => {
const abortCtrl = useMemo(() => new AbortController(), [])
// a priori
, url = useRef("")
, opt = useRef({})
const [res, setRes] = useState(null)
, [err, setErr] = useState(null)
, [isPending, setIsPending] = useState(false)
const run = ({ onOk, onErr, onFin }) => {
setIsPending(true)
// reseteo por si re-utilizo el hook
setRes(null)
setErr(null)
const options = Object.assign({ signal: abortCtrl.signal }, opt.current)
fetch(url.current, options)
.then(async res => {
if (!res.ok) throw await res.json();
return await res.json();
})
.then(data => {
if (typeof(onOk) === "function") onOk(data);
setRes(data)
})
.catch(e => {
if (e.name === "AbortError") return;
setErr(true)
setRes(e)
if (typeof(onErr) === "function") onErr(e);
})
.finally(() => {
setIsPending(false)
if (typeof(onFin) === "function") onFin();
})
}
useEffect(() => {
return () => abortCtrl.abort() // cleanup func
// eslint-disable-next-line
}, [])
return { url, opt, run, res, err, isPending }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment