// via https://raw.githubusercontent.com/streamich/react-use/master/src/useAsyncFn.ts import { DependencyList, useCallback, useState } from 'react' import useRefMounted from './useRefMounted' export type AsyncState = | { loading: boolean error?: undefined value?: undefined } | { loading: false error: Error value?: undefined } | { loading: false error?: undefined value: T } export type AsyncFn = [ AsyncState, (...args: Args | []) => Promise ] export function useAsyncFn( fn: (...args: Args | []) => Promise, deps: DependencyList = [], initialState: AsyncState = { loading: false }, ): AsyncFn { const [state, set] = useState>(initialState) const mounted = useRefMounted() const callback = useCallback((...args: Args | []) => { set({ loading: true }) return fn(...args).then( value => { if (mounted.current) { set({ value, loading: false }) } return value }, error => { if (mounted.current) { set({ error, loading: false }) } return error }, ) }, deps) return [state, callback] }