useActorSuspenseQuery
useActorSuspenseQuery is a React hook for fetching data from canisters with Suspense support. It suspends the component until data is available, eliminating the need for loading state handling.
Import
Section titled “Import”import { createActorHooks } from "@ic-reactor/react"import { backend } from "./reactor"
const { useActorSuspenseQuery } = createActorHooks(backend)import { Suspense } from "react"import { useActorSuspenseQuery } from "./reactor"
function UserProfile({ userId }: { userId: string }) { // This hook suspends until data is loaded const { data } = useActorSuspenseQuery({ functionName: "get_user", args: [userId], })
// data is ALWAYS defined here - no undefined check needed return ( <div> <h1>{data.name}</h1> <p>{data.email}</p> </div> )}
// Must be wrapped in Suspensefunction App() { return ( <Suspense fallback={<Loading />}> <UserProfile userId="user-123" /> </Suspense> )}Options
Section titled “Options”UseActorSuspenseQueryParameters extends react-query’s QueryObserverOptions, giving you access to all standard react-query options plus our custom actor options.
Same as useActorQuery except:
Key Options
Section titled “Key Options”| Option | Type | Default | Description |
|---|---|---|---|
functionName |
string |
Required | The canister method to call |
args |
array |
[] |
Arguments to pass to the method |
staleTime |
number |
1000 |
Time in ms before data is considered stale. TanStack Query raises any lower value, 0 included, to 1 s |
select |
function |
- | Transform the data before returning |
Return Value
Section titled “Return Value”Returns a TanStack Query suspense result. The key difference from useActorQuery:
| Property | Type | Description |
|---|---|---|
data |
TData |
Always defined (never undefined) |
error |
TError | null |
A failed first load is thrown to the Error Boundary. A failed refetch keeps data and sets this |
status |
'success' | 'error' |
'error' after a failed refetch; the component suspends until there is data |
Examples
Section titled “Examples”Basic Suspense Query
Section titled “Basic Suspense Query”import { Suspense } from "react"import { useActorSuspenseQuery } from "./reactor"
function Greeting() { const { data } = useActorSuspenseQuery({ functionName: "greet", args: ["World"], })
// data is guaranteed to be defined return <h1>{data}</h1>}
function App() { return ( <Suspense fallback={<div>Loading...</div>}> <Greeting /> </Suspense> )}Multiple Suspense Queries
Section titled “Multiple Suspense Queries”Two suspense queries in the same component run one after the other: the first hook suspends the component, so the second call starts only once the first has returned. Give each query its own component under one boundary and they start together:
import { Suspense } from "react"import { useActorSuspenseQuery } from "./reactor"
function Dashboard({ userId }: { userId: string }) { // Sibling components suspend separately, so both calls start at once return ( <Suspense fallback={<Loading />}> <Welcome userId={userId} /> <UserStats userId={userId} /> </Suspense> )}
function Welcome({ userId }: { userId: string }) { const { data: user } = useActorSuspenseQuery({ functionName: "get_user", args: [userId], }) return <h1>Welcome, {user.name}</h1>}
function UserStats({ userId }: { userId: string }) { const { data: stats } = useActorSuspenseQuery({ functionName: "get_user_stats", args: [userId], }) return <Stats data={stats} />}With Select
Section titled “With Select”import { useActorSuspenseQuery } from "./reactor"
function Hello({ userId }: { userId: string }) { const { data: userName } = useActorSuspenseQuery({ functionName: "get_user", args: [userId], select: (user) => user.name, // data is just the name string })
return <h1>Hello, {userName}</h1>}Nested Suspense Boundaries
Section titled “Nested Suspense Boundaries”import { Suspense } from "react"
function App() { return ( <Suspense fallback={<PageSkeleton />}> <Header /> {/* Has its own data */} <Suspense fallback={<ContentSkeleton />}> <MainContent /> {/* Independent loading */} </Suspense> <Suspense fallback={<SidebarSkeleton />}> <Sidebar /> {/* Independent loading */} </Suspense> </Suspense> )}Error Handling with Error Boundaries
Section titled “Error Handling with Error Boundaries”import { Suspense } from "react"import { ErrorBoundary, type FallbackProps } from "react-error-boundary"
function ErrorFallback({ error, resetErrorBoundary }: FallbackProps) { return ( <div className="error"> <p>Something went wrong:</p> <pre>{error instanceof Error ? error.message : String(error)}</pre> <button onClick={resetErrorBoundary}>Try again</button> </div> )}
function App() { return ( <ErrorBoundary FallbackComponent={ErrorFallback}> <Suspense fallback={<Loading />}> <UserProfile userId="user-123" /> </Suspense> </ErrorBoundary> )}With Stale Time
Section titled “With Stale Time”import { useActorSuspenseQuery } from "./reactor"
function Settings() { const { data } = useActorSuspenseQuery({ functionName: "get_config", args: [], staleTime: 5 * 60 * 1000, // Fresh for 5 minutes })
return <pre>{JSON.stringify(data)}</pre>}Sequential Suspense (Waterfall)
Section titled “Sequential Suspense (Waterfall)”import { useActorSuspenseQuery } from "./reactor"
function UserPosts({ userId }: { userId: string }) { // This query runs first const { data: user } = useActorSuspenseQuery({ functionName: "get_user", args: [userId], })
// This query runs after user is loaded const { data: posts } = useActorSuspenseQuery({ functionName: "get_user_posts", args: [user.id], // Uses data from first query })
return <PostList posts={posts} author={user.name} />}When to Use Suspense
Section titled “When to Use Suspense”✅ Use Suspense when:
- You always need the data (no conditional fetching)
- You want cleaner components without loading state
- You want loading states at the boundary level
❌ Use regular useActorQuery when:
- You need conditional fetching (
enabledoption) - You want per-component loading UI
- You need to access
isPendingorisFetchingstates
See Also
Section titled “See Also”- useActorQuery — Regular query hook
- useActorSuspenseInfiniteQuery — Suspense pagination
- Queries Guide — In-depth query patterns
- createActorHooks — Creating hooks