Last active
March 20, 2024 21:47
-
-
Save lejonmanen/ce5f2a70499f732bf2418f0f12492267 to your computer and use it in GitHub Desktop.
React hook for sending fetch requests and cancelling them safely.
This file contains 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 { useEffect, useRef } from 'react' | |
/* | |
Safely send and cancel one AJAX request at the time. If you need to send multiple requests at the same time, call this hook several times. | |
Usage: | |
const [cancelRef, doAjax] = useCancellableAjax() | |
Fetch data. Tip: use a setState function as callback. | |
doAjax(url, fetchOptions, dataCallback) | |
Cancel a AJAX request. Cancel function only exists if the request is active. Note: you do not need to call the cancel function if the component is unmounted, this hook will take care of that. | |
if( cancelRef.current ) { cancelRef.current() } | |
*/ | |
export default function useCancellableAjax() { | |
const cancelRef = useRef(null) | |
useEffect(() => { | |
return () => { | |
// Cancels the request if component is unmounted | |
if( cancelRef.current ) | |
cancelRef.current(); | |
}; | |
}, []) | |
const ajaxFunction = (url, fetchOptions, saveData) => { | |
const controller = new AbortController(); | |
// Cancel function | |
cancelRef.current = () => { | |
controller.abort() | |
cancelRef.current = null | |
} | |
fetch(url, { ...fetchOptions, signal: controller.signal }) | |
.then(response => response.json()) | |
.then(data => { | |
// Remove the cancel function when the request is complete | |
cancelRef.current = null; | |
saveData(data) | |
}) | |
.catch(error => { | |
// Cancel is expected behavior, should not throw | |
if( error.name !== 'AbortError' ) { | |
throw error; | |
} | |
}) | |
} | |
return [cancelRef, ajaxFunction] | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment