porridger/front/src/hooks/api/useFetch.js

58 lines
1.8 KiB
JavaScript

import { useEffect, useRef, useState } from "react"
import { isAborted } from '../../utils'
const useFetch = (url, params, initialData) => {
const [data, setData] = useState(initialData)
const [loading, setLoading] = useState(true)
const [error, setError] = useState("")
const abortControllerRef = useRef(null)
useEffect(() => {
if (abortControllerRef.current) {
abortControllerRef.current.abort()
}
const abortController = new AbortController()
abortControllerRef.current = abortController
fetch(url, { ...params, signal: abortControllerRef.current.signal })
.then(res => {
if (!res.ok) {
switch (res.status) {
case 401:
throw new Error("Ошибка авторизации")
case 404:
throw new Error("Объект не найден")
default: {
throw new Error("Ошибка ответа от сервера")
}
}
}
return res.json()
})
.then(data => {
setData(data)
setLoading(false)
})
.catch(err => {
if (!isAborted(err)) {
setError("Ошибка сети")
}
setLoading(false)
if (import.meta.env.DEV) {
console.log(url, params, err)
}
})
return () => abortControllerRef.current.abort()
}, [url, params])
return { data, loading, error, abort: abortControllerRef.current?.abort }
}
export default useFetch