import { useState , useEffect } from 'react' ; import { query } from './query' ; import fetcher from './fetcher' ; import { Options , QueryResult , Deps , Refetch } from './types' ; function getDeps ( options ? ) { if ( options && Array . isArray ( options . deps ) ) return options . deps ; return [ ] ; } export function useQuery < T = any > ( input , options = { } ) { let unmounted = false ; const initialState = { loading : true } as QueryResult < T > ; const deps = getDeps ( options ) ; const [ result , setState ] = useState ( initialState ) ; const fetchData = async ( opt = { } ) => { setState ( prev => ( { ... prev , loading : true } ) ) ; try { const data = await query < T > ( input , opt || { } ) ; if ( ! unmounted ) setState ( prev => ( { ... prev , loading : false , data } ) ) ; return data ; } catch ( error ) { if ( ! unmounted ) setState ( prev => ( { ... prev , loading : false , error } ) ) ; return error ; } } ; const refetch = async < P = any > ( opt ? ) : Promise < P > => { const refetchedData = await fetchData ( opt ) ; return refetchedData as P ; } ; useEffect ( ( ) => { fetchData ( options ) ; if ( options && options . name ) { fetcher [ options . name ] = { refetch } ; } return ( ) => { unmounted = true ; } ; } , deps ) ; return { ... result , refetch } ; }