Skip to content

Instantly share code, notes, and snippets.

@jpillora
Created January 6, 2022 05:55
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jpillora/7c633e6eec48e15a678f03a0b88fec44 to your computer and use it in GitHub Desktop.
Save jpillora/7c633e6eec48e15a678f03a0b88fec44 to your computer and use it in GitHub Desktop.
useAsync.ts
import { useCallback, useEffect, useState } from 'react'
// borrowed from https://usehooks.com/useAsync/
export function useAsync<T>(asyncFunction: () => Promise<T>, immediate = true) {
const [loading, setLoading] = useState(true)
const [value, setValue] = useState<T | null>(null)
const [error, setError] = useState<any>(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(async () => {
setValue(null)
setError(null)
try {
const response = await asyncFunction()
setValue(response)
return response
} catch (error) {
setError(error)
} finally {
setLoading(false)
}
}, [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) {
void execute()
}
}, [execute, immediate])
return { execute, loading, value, error }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment