forked from polka_billy/porridger
58 lines
1.8 KiB
JavaScript
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
|