Skip to content

useAsync

Resolves synchronously any asynchronous function that you have, returning the data itself along with loading and error states.

Installation

npx rabbithook@latest add use-async

Usage

App.tsx
import useAsync from "@/hooks/use-async";
function Component() {
const { value, loading, error } = useAsync(() => {
const response = await fetch("...");
return response.json()
});
return (
<div>
{loading && <p>Loading...</p>}
{error && <p>Error: {error.message}</p>}
{value && <p>Value: {value}</p>}
</div>
)
}

Code

use-async.ts
import { useCallback, useEffect, useState } from "react"
type AsyncState<T> = {
loading: boolean;
error: string | null;
value: T | null;
}
function useAsync<T>(callback: () => Promise<T>, dependencies: unknown[] = []): AsyncState<T> {
const [loading, setLoading] = useState<boolean>(true);
const [error, setError] = useState<string | null>(null);
const [value, setValue] = useState<T | null>(null);
const callbackMemoized = useCallback(() => {
setLoading(true);
setError(null);
setValue(null);
callback()
.then(setValue)
.catch(setError)
.finally(() => setLoading(false))
}, [...dependencies, callback])
useEffect(() => {
callbackMemoized();
}, [callbackMemoized])
return { loading, error, value }
}
export default useAsync;