-
-
Save MrRedu/9bf5a1f42935a3dc736b86e6920c855e 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 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, 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