/* eslint-disable */ import { DependencyList, useCallback, useState, useRef } from 'react'; import useMountedState from './useMountedState'; 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 default function useAsyncFn( fn: (...args: Args | []) => Promise, deps: DependencyList = [], initialState: AsyncState = { loading: false } ): AsyncFn { const lastCallId = useRef(0); const [state, set] = useState>(initialState); const isMounted = useMountedState(); const callback = useCallback((...args: Args | []) => { const callId = ++lastCallId.current; set({ loading: true }); return fn(...args).then( value => { isMounted() && callId === lastCallId.current && set({ value, loading: false }); return value; }, error => { isMounted() && callId === lastCallId.current && set({ error, loading: false }); return error; } ); }, deps); return [state, callback]; }