-
-
Save JamesBliss/4dcddabad92081e724d79869912126c8 to your computer and use it in GitHub Desktop.
A generic React fetch hook for API calls with caching, error handling, and refetch capability
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 { 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