11import { useEffect , useState , useCallback } from 'react'
22
3- export function useFetch ( url , options ) {
4- // if on server, return loading
5- if ( ! global . window ) return Object . assign ( [ null , true , null ] , { data : null , loading : true , error : null } )
3+ const isObject = obj => obj === Object ( obj ) && Object . prototype . toString . call ( obj ) !== '[object Array]'
4+
5+ export function useFetch ( arg1 , arg2 ) {
6+ let url = null
7+ let options = { }
8+ let onMount = false
9+ let baseUrl = ''
10+ let method = 'GET'
11+
12+ if ( typeof arg1 === 'string' ) {
13+ url = arg1
14+ if ( isObject ( arg2 ) ) options = arg2
15+ } else if ( isObject ( arg1 ) ) {
16+ const fetchObj = arg1
17+ if ( true ) {
18+ // take out all the things that are not normal `fetch` options
19+ // need to take this out of scope so can set the variables below correctly
20+ let { url, onMount, timeout, baseUrl, ...rest } = fetchObj
21+ options = rest
22+ }
23+ if ( fetchObj . url ) url = fetchObj . url
24+ if ( fetchObj . onMount ) onMount = fetchObj . onMount
25+ if ( fetchObj . method ) method = fetchObj . method
26+ if ( fetchObj . baseUrl ) baseUrl = fetchObj . baseUrl
27+ }
628
729 const [ data , setData ] = useState ( null )
8- const [ loading , setLoading ] = useState ( true )
30+ const [ loading , setLoading ] = useState ( onMount )
931 const [ error , setError ] = useState ( null )
1032
11- const fetchData = useCallback ( async ( ) => {
33+ const fetchData = useCallback ( method => async ( fArg1 , fArg2 ) => {
34+ let query = ''
35+ const fetchOptions = { }
36+ if ( isObject ( fArg1 ) && method !== 'GET' ) {
37+ fetchOptions . body = JSON . stringify ( fArg1 )
38+ } else if ( baseUrl && typeof fArg1 === 'string' ) {
39+ url = baseUrl + fArg1
40+ if ( isObject ( fArg2 ) ) fetchOptions . body = JSON . stringify ( fArg2 )
41+ }
42+ if ( typeof fArg1 === 'string' && typeof fArg2 === 'string' ) {
43+ const base = fArg1
44+ query = fArg2
45+ url = base + query
46+ }
47+
1248 try {
1349 setLoading ( true )
14- const response = await fetch ( url , options )
50+ const response = await fetch ( url + query , {
51+ method,
52+ ...options ,
53+ ...fetchOptions ,
54+ } )
1555 let data = null
1656 try {
1757 data = await response . json ( )
18- } catch ( Error ) {
19- data = await response . text ( )
58+ } catch ( err ) {
59+ try {
60+ data = await response . text ( )
61+ } catch ( err ) {
62+ setError ( `Currently only supports JSON and Text response types: ${ err } ` )
63+ }
2064 }
2165 setData ( data )
2266 setLoading ( false )
@@ -25,11 +69,22 @@ export function useFetch(url, options) {
2569 }
2670 } , [ url ] )
2771
72+ const get = useCallback ( fetchData ( 'GET' ) )
73+ const post = useCallback ( fetchData ( 'POST' ) )
74+ const patch = useCallback ( fetchData ( 'PATCH' ) )
75+ const put = useCallback ( fetchData ( 'PUT' ) )
76+ const del = useCallback ( fetchData ( 'DELETE' ) )
77+
78+ const request = { get, post, patch, put, del, delete : del }
79+
2880 useEffect ( ( ) => {
29- fetchData ( )
81+ if ( onMount ) request [ method . toLowerCase ( ) ] ( )
3082 } , [ fetchData ] )
3183
32- return Object . assign ( [ data , loading , error ] , { data, loading, error } )
84+ return Object . assign (
85+ [ data , loading , error , request ] ,
86+ { data, loading, error, request, ...request }
87+ )
3388}
3489
3590export default useFetch
0 commit comments