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”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/core"
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"]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