// Dependencies import React from 'react'; type FetchAsync = () => Promise; export interface Fetch { loading: boolean; error?: unknown; response?: E; fetch: () => void; } export function useFetch, E>(callback: T, initValue?: E): Fetch { const [response, setResponse] = React.useState(initValue); const [loading, setLoading] = React.useState(false); const [error, setError] = React.useState(undefined); const fetcher = React.useCallback(() => { setLoading(true); callback() .then(setResponse) .catch(setError) .finally(() => setLoading(false)); }, [callback]); React.useEffect(fetcher, [fetcher]); return { loading, error, response, fetch: fetcher }; } type CallbackAsync = (...args: never[]) => Promise; export function useAsyncCallback(callback: T): [T, boolean, unknown] { const [loading, setLoading] = React.useState(false); const [error, setError] = React.useState(undefined); const asyncCallback = React.useCallback((...args: never[]) => { setLoading(true); return callback(...args) .catch(setError) .finally(() => setLoading(false)); }, [callback]); return [asyncCallback as T, loading, error]; } export default useFetch;