Created
June 17, 2023 21:23
-
-
Save alexandrius/d90fa0ed172ddf5b25b75dfd664f8bb1 to your computer and use it in GitHub Desktop.
use-fetch-hook
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { baseUrl } from 'env'; | |
function handleResponse(response) { | |
return response.text().then((text) => { | |
const data = text && JSON.parse(text); | |
if (!response.ok) { | |
const error = (data && data.error) || response.statusText; | |
return Promise.reject(error); | |
} | |
return data; | |
}); | |
} | |
function handleError(error) { | |
return Promise.reject(error); | |
} | |
function _fetch(endpoint, requestOptions) { | |
return fetch(`${baseUrl}${endpoint}`, requestOptions).then(handleResponse).catch(handleError); | |
} | |
function getEndpointWithParams(endpoint, params) { | |
let endpointWithParams = endpoint; | |
if (params) { | |
// eslint-disable-next-line no-undef | |
const urlSearchParams = new URLSearchParams(params); | |
endpointWithParams += `?${urlSearchParams.toString()}`; | |
} | |
return endpointWithParams; | |
} | |
function get({ endpoint, params, signal }) { | |
const requestOptions = { | |
method: 'GET', | |
signal, | |
}; | |
return _fetch(getEndpointWithParams(endpoint, params), requestOptions); | |
} | |
function post({ endpoint, params, body, signal }) { | |
const requestOptions = { | |
method: 'POST', | |
headers: { 'Content-Type': 'application/json' }, | |
body: JSON.stringify(body), | |
signal, | |
}; | |
return _fetch(getEndpointWithParams(endpoint, params), requestOptions); | |
} | |
function put({ endpoint, params, body, signal }) { | |
const requestOptions = { | |
method: 'PUT', | |
headers: { 'Content-Type': 'application/json' }, | |
body: JSON.stringify(body), | |
signal, | |
}; | |
return _fetch(getEndpointWithParams(endpoint, params), requestOptions); | |
} | |
function del({ endpoint, signal }) { | |
const requestOptions = { | |
method: 'DELETE', | |
signal, | |
}; | |
return _fetch(endpoint, requestOptions); | |
} | |
export { get, post, put, del }; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { useCallback, useEffect, useRef, useState } from 'react'; | |
import * as methods from './fetch'; | |
export default function useFetch({ endpoint, params, body, method, requestOnMount = true }) { | |
// eslint-disable-next-line no-undef | |
const abortController = useRef(new AbortController()).current; | |
const request = useCallback(() => { | |
const { signal } = abortController; | |
methods[method]({ endpoint, signal, params, body }) | |
.then((response) => { | |
setRequestState((state) => ({ ...requestState, loading: false, response })); | |
}) | |
.catch((error) => setRequestState((state) => ({ ...requestState, loading: false, error }))); | |
}, []); | |
const [requestState, setRequestState] = useState({ | |
error: null, | |
response: null, | |
request, | |
loading: requestOnMount, | |
}); | |
useEffect(() => { | |
if (requestOnMount) { | |
request(); | |
} | |
return () => { | |
abortController.abort(); | |
}; | |
}, []); | |
return requestState; | |
} | |
export function useGet(endpoint, params) { | |
return useFetch({ endpoint, ...params, method: 'get' }); | |
} | |
export function usePost(endpoint, body, params) { | |
return useFetch({ endpoint, body, ...params, method: 'post' }); | |
} | |
export function usePut(endpoint, body, params) { | |
return useFetch({ endpoint, body, ...params, method: 'put' }); | |
} | |
export function useDelete(endpoint, params) { | |
return useFetch({ endpoint, ...params, method: 'del' }); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment