Skip to content

Instantly share code, notes, and snippets.

@weslleyaraujo
Created May 4, 2021 20:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save weslleyaraujo/98136d1e9d51204ee9e1376a7927b98b to your computer and use it in GitHub Desktop.
Save weslleyaraujo/98136d1e9d51204ee9e1376a7927b98b to your computer and use it in GitHub Desktop.
const useAsync = <T, E = string>(
asyncFunction: () => Promise<T>,
immediate = true
) => {
const [status, setStatus] = useState<
"idle" | "pending" | "success" | "error"
>("idle");
const [value, setValue] = useState<T | null>(null);
const [error, setError] = useState<E | null>(null);
// The execute function wraps asyncFunction and
// handles setting state for pending, value, and error.
// useCallback ensures the below useEffect is not called
// on every render, but only if asyncFunction changes.
const execute = useCallback(() => {
setStatus("pending");
setValue(null);
setError(null);
return asyncFunction()
.then((response: any) => {
setValue(response);
setStatus("success");
})
.catch((error: any) => {
setError(error);
setStatus("error");
});
}, [asyncFunction]);
// Call execute if we want to fire it right away.
// Otherwise execute can be called later, such as
// in an onClick handler.
useEffect(() => {
if (immediate) {
execute();
}
}, [execute, immediate]);
return { execute, status, value, error };
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment