Improved loading handling

This commit is contained in:
2023-07-31 14:55:12 +03:00
parent 9b35a54ae9
commit e7327945e3
6 changed files with 85 additions and 35 deletions

View File

@ -3,29 +3,44 @@ import { useEffect, useState } from 'react'
import useSend from './useSend'
type UseFetchShared = {
loading: boolean,
abort?: () => void,
refetch: () => void,
}
type UseFetchSucced<T> = {
error: null,
data: T,
loading: false,
error: null,
} & UseFetchShared
type UseFetchLoading = {
data: undefined,
loading: true,
error: null,
} & UseFetchShared
type UseFetchErrored = {
error: string,
data: undefined,
loading: false,
error: string,
} & UseFetchShared
type UseFetchReturn<T> = UseFetchSucced<T> | UseFetchErrored
type UseFetchReturn<T> = UseFetchSucced<T> | UseFetchLoading | UseFetchErrored
const gotError = <T>(res: UseFetchReturn<T>): res is UseFetchErrored => (
typeof res.error === 'string'
)
const fallbackError = <T>(res: UseFetchReturn<T>) => (
gotError(res) ? res.error : res.data
function fallbackError<T>(res: UseFetchSucced<T> | UseFetchErrored): T | string
function fallbackError<T>(res: UseFetchReturn<T>): T | string | undefined
function fallbackError<T>(res: UseFetchReturn<T>): T | string | undefined {
return (
gotError(res) ? res.error : res.data
)
}
const gotResponse = <T>(res: UseFetchReturn<T>): res is UseFetchSucced<T> | UseFetchErrored => (
!res.loading
)
function useFetch<R, T extends NonNullable<unknown>>(
@ -59,13 +74,28 @@ function useFetch<R, T extends NonNullable<unknown>>(
useEffect(refetch, [doSend])
if (loading === true) {
return {
data: undefined,
loading,
error: null,
refetch,
}
}
if (error !== null) {
return {
data: undefined,
loading,
error,
refetch,
}
}
return {
...(
error === null ? ({
data: data!, error: null,
}) : ({ data: undefined, error })
),
data: data!,
loading,
error,
refetch,
}
}
@ -74,4 +104,4 @@ export type { UseFetchReturn }
export default useFetch
export { gotError, fallbackError }
export { gotError, gotResponse, fallbackError }