You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
55 lines
1.2 KiB
55 lines
1.2 KiB
import { useCallback } from 'react'; |
|
|
|
import api from '../lib/api'; |
|
import handleAPIError from '../lib/handleAPIError'; |
|
import useProtectedState from './useProtectedState'; |
|
|
|
type ActiveFetchSetter<T> = (data: T) => void; |
|
|
|
type ActiveFetcher = (url?: string) => void; |
|
|
|
type ActiveFetchHookResponse = { |
|
fetch: ActiveFetcher; |
|
loading: boolean; |
|
}; |
|
|
|
const useActiveFetch = <Data>( |
|
options: { |
|
onData?: ActiveFetchSetter<Data>; |
|
onError?: (emsg: Message) => void; |
|
url?: string; |
|
} = {}, |
|
): ActiveFetchHookResponse => { |
|
const { onError, onData, url: urlPrefix = '' } = options; |
|
|
|
const [loading, setLoading] = useProtectedState<boolean>(false); |
|
|
|
const fetch = useCallback<ActiveFetcher>( |
|
(urlPostfix = '') => { |
|
const url = `${urlPrefix}${urlPostfix}`; |
|
|
|
if (!url) return; |
|
|
|
setLoading(true); |
|
|
|
api |
|
.get<Data>(url) |
|
.then(({ data }) => { |
|
onData?.call(null, data); |
|
}) |
|
.catch((error) => { |
|
const emsg = handleAPIError(error); |
|
|
|
onError?.call(null, emsg); |
|
}) |
|
.finally(() => { |
|
setLoading(false); |
|
}); |
|
}, |
|
[urlPrefix, setLoading, onError, onData], |
|
); |
|
|
|
return { fetch, loading }; |
|
}; |
|
|
|
export default useActiveFetch;
|
|
|