React
Install the adapter alongside React 18.3 or newer:
pnpm add @omni-async/react
Query
import { useQuery } from "@omni-async/react";
function Search() {
const results = useQuery(
async (term: string) => {
const response = await fetch(`/api/search?q=${encodeURIComponent(term)}`);
if (!response.ok) throw new Error("Search failed");
return response.json() as Promise<string[]>;
},
{ initial: () => [] },
);
return (
<>
<button disabled={results.loading} onClick={() => void results.trigger("async")}>
Search
</button>
{results.error ? <p>Search failed</p> : null}
<ul>
{results.data.map((item) => (
<li key={item}>{item}</li>
))}
</ul>
</>
);
}
useQuery uses latest-request concurrency. Its initial function supplies initial data and is called again to produce fallback data after an error.
Fetch on mount
const users = useFetch(
async (signal) => {
const response = await fetch("/api/users", { signal });
return response.json() as Promise<User[]>;
},
{ initial: () => [] },
);
useFetch starts on mount, aborts the previous fetch before a new one, and aborts during cleanup.