useActorQuery
useActorQuery is a React hook for fetching data from Internet Computer canisters. It wraps TanStack Query’s useQuery with canister-specific functionality.
Import
Section titled “Import”import { createActorHooks } from "@ic-reactor/react"
const { useActorQuery } = createActorHooks(backend)function UserProfile({ userId }: { userId: string }) { const { data, isPending, error } = useActorQuery({ functionName: "getUser", args: [userId], })
if (isPending) return <div>Loading...</div> if (error) return <div>Error: {error.message}</div>
return <div>{data?.name}</div>}Options
Section titled “Options”UseActorQueryParameters extends react-query’s QueryObserverOptions, giving you access to all standard react-query options plus our custom actor options.
Required Options
Section titled “Required Options”| Option | Type | Description |
|---|---|---|
functionName |
string |
The canister method to call |
Optional Options
Section titled “Optional Options”| Option | Type | Default | Description |
|---|---|---|---|
args |
array |
[] |
Arguments to pass to the method |
enabled |
boolean |
true |
Whether the query should run |
staleTime |
number |
0 |
Time in ms before data is considered stale |
gcTime |
number |
300000 |
Time in ms before unused data is garbage collected |
refetchInterval |
number | false |
false |
Polling interval in ms |
refetchOnWindowFocus |
boolean |
true |
Refetch when window regains focus |
refetchOnMount |
boolean |
true |
Refetch when component mounts |
refetchOnReconnect |
boolean |
true |
Refetch when network reconnects |
retry |
number | boolean |
3 |
Number of retry attempts |
retryDelay |
number | function |
exponential | Delay between retries |
select |
function |
- | Transform the data before returning |
queryKey |
array |
- | Additional query key segments |
callConfig |
CallConfig |
- | IC agent call configuration |
Return Value
Section titled “Return Value”Returns a TanStack Query result object:
| Property | Type | Description |
|---|---|---|
data |
TData | undefined |
The resolved data |
error |
Error | null |
Error if query failed |
status |
'pending' | 'error' | 'success' |
Query status |
isPending |
boolean |
True if no data yet |
isError |
boolean |
True if query errored |
isSuccess |
boolean |
True if query succeeded |
isFetching |
boolean |
True if fetching (including background) |
isRefetching |
boolean |
True if refetching |
refetch |
function |
Manually trigger a refetch |
dataUpdatedAt |
number |
Timestamp of last data update |
Examples
Section titled “Examples”Basic Query
Section titled “Basic Query”const { data, isPending, error } = useActorQuery({ functionName: "greet", args: ["World"],})Conditional Query
Section titled “Conditional Query”const { data } = useActorQuery({ functionName: "getUser", args: [userId], enabled: !!userId, // Only fetch when userId exists})With Select
Section titled “With Select”// Extract only the name from the user objectconst { data: userName } = useActorQuery({ functionName: "getUser", args: [userId], select: (user) => user?.name,})Stale Time Configuration
Section titled “Stale Time Configuration”// Data stays fresh for 5 minutesconst { data } = useActorQuery({ functionName: "getConfig", args: [], staleTime: 5 * 60 * 1000,})
// Data is never staleconst { data } = useActorQuery({ functionName: "getMetadata", args: [], staleTime: Infinity,})Polling
Section titled “Polling”// Refetch every 10 secondsconst { data } = useActorQuery({ functionName: "getPrice", args: [], refetchInterval: 10_000,})Manual Refetch
Section titled “Manual Refetch”const { data, refetch, isFetching } = useActorQuery({ functionName: "getNotifications", args: [],})
return ( <div> <NotificationList data={data} /> <button onClick={() => refetch()} disabled={isFetching}> Refresh </button> </div>)Error Handling
Section titled “Error Handling”import { CanisterError, CallError } from "@ic-reactor/react"
const { data, error, isError } = useActorQuery({ functionName: "getBalance", args: [principal],})
if (isError) { if (error instanceof CanisterError) { // Business logic error from canister return ( <div> Canister error [{error.code}]: {JSON.stringify(error.err)} </div> ) } // Network or other error return <div>Error: {error.message}</div>}Type-Safe Queries
Section titled “Type-Safe Queries”// TypeScript infers types from your canister interfaceconst { data } = useActorQuery({ functionName: "getUser", // ✅ Autocompletes valid methods args: ["user-123"], // ✅ Type-checked})// data is typed as User | undefinedWith Custom Query Key
Section titled “With Custom Query Key”// Add custom segments to the query keyconst { data } = useActorQuery({ functionName: "getData", args: [], queryKey: ["version", "2"],})// Full key: [canisterId, "getData", "[]", "version", "2"]The args segment is the JSON-serialized args array, so an empty args: []
still contributes the literal "[]". Custom queryKey segments are appended
after it, never in place of the identity prefix.
Dependent Queries
Section titled “Dependent Queries”function UserPosts({ userId }: { userId: string }) { // First query const { data: user } = useActorQuery({ functionName: "getUser", args: [userId], })
// Dependent query - only runs when user exists const { data: posts } = useActorQuery({ functionName: "getUserPosts", args: [user?.id ?? ""], enabled: !!user?.id, })
return <PostList posts={posts} />}Type Parameters
Section titled “Type Parameters”useActorQuery< M extends FunctionName<A>, // Method name TSelected = ReturnType // Type after select>(options: UseActorQueryConfig<A, M, T, TSelected>)The types are automatically inferred from your actor interface, so you typically don’t need to specify them manually.
See Also
Section titled “See Also”- Queries Guide — In-depth guide to queries
- useActorSuspenseQuery — Suspense version
- useActorInfiniteQuery — For pagination
- createActorHooks — Creating hooks