Skip to content

Instantly share code, notes, and snippets.

@KristofferEriksson
Created January 29, 2024 21:27
Show Gist options
  • Save KristofferEriksson/5184996b65fb128e237dfa0a519e51f4 to your computer and use it in GitHub Desktop.
Save KristofferEriksson/5184996b65fb128e237dfa0a519e51f4 to your computer and use it in GitHub Desktop.
A generic React fetch hook for API calls with caching, error handling, and refetch capability
import { useCallback, useEffect, useState } from "react";
type FetchState<T> = {
data: T | null;
isLoading: boolean;
error: Error | null;
isCached: boolean;
refetch: () => void;
};
// A generic fetch hook for API calls with caching, error handling, and refetch capability
function useFetch<T = unknown>(
url: string,
options?: RequestInit
): FetchState<T> {
const [state, setState] = useState<FetchState<T>>({
data: null,
isLoading: true,
error: null,
isCached: false,
refetch: () => {},
});
const fetchData = useCallback(
async (ignoreCache: boolean = false) => {
setState((prevState) => ({ ...prevState, isLoading: true }));
try {
let data: T;
let isCached = false;
const cache = sessionStorage.getItem(url);
if (cache && !ignoreCache) {
data = JSON.parse(cache) as T;
isCached = true;
} else {
const response = await fetch(url, options);
if (!response.ok) {
throw new Error(`Error: ${response.status}`);
}
data = await response.json();
sessionStorage.setItem(url, JSON.stringify(data));
}
setState({
data,
isLoading: false,
error: null,
isCached,
refetch: () => fetchData(true),
});
} catch (error) {
setState((prevState) => ({
...prevState,
data: null,
isLoading: false,
error: error as Error,
}));
}
},
[url, options]
);
// Triggering the fetch operation when the URL or options change
useEffect(() => {
fetchData();
}, [fetchData]);
return state;
}
export default useFetch;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment