Created
January 29, 2024 21:27
-
-
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
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