Skip to content

Instantly share code, notes, and snippets.

@signalwerk
Created January 10, 2024 22:59
Show Gist options
  • Save signalwerk/e020bd8b605ddc380a28606bd9be887d to your computer and use it in GitHub Desktop.
Save signalwerk/e020bd8b605ddc380a28606bd9be887d to your computer and use it in GitHub Desktop.
Fetch a JSON and have the option to chancel the request
import { useState, useEffect } from "react";
const useFetch = (url, options) => {
const [response, setResponse] = useState(null);
const [error, setError] = useState(null);
const [loading, setLoading] = useState(false);
const abortController = new AbortController(); // Move abortController outside useEffect
useEffect(() => {
const signal = abortController.signal;
const doFetch = async () => {
setLoading(true);
try {
const res = await fetch(url, { ...options, signal });
const json = await res.json();
if (!signal.aborted) {
setResponse(json);
}
} catch (e) {
if (!signal.aborted) {
setError(e);
}
} finally {
if (!signal.aborted) {
setLoading(false);
}
}
};
doFetch();
return () => {
abortController.abort();
};
}, [url, options]);
return { response, error, loading, abortController }; // Return abortController here
};
export default useFetch;
/*
import React from "react";
import useFetch from "./useFetch";
const MyComponent = () => {
const { response, error, loading, abortController } = useFetch(
"https://api.example.com/data",
{}
);
const handleCancel = () => {
abortController.abort(); // Call abort method when the button is clicked
};
return (
<div>
{loading && (
<>
<div>Loading...</div>
<button onClick={handleCancel}>Cancel Request</button>{" "}
</>
)}
{error && <div>Error: {error.message}</div>}
{response && (
<div>
<h1>Data Fetched</h1>
<pre>{JSON.stringify(response, null, 2)}</pre>
</div>
)}
</div>
);
};
export default MyComponent;
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment