Skip to Content
DocsReact HooksQueries & Parallel Fetching

Queries & Parallel Fetching

Actyx RPC provides hooks for fetching, parallel loading, and caching remote server query states.


useQuery

Fetch and monitor single procedure states:

import { useQuery } from "@explita/actyx-rpc/react"; import { getUser } from "@/backend/procedures"; function UserProfile({ userId }) { const { data, isFetching, isRefetching, isFetched, isEmpty, error, refetch, reset, } = useQuery(() => getUser({ id: userId }), { enabled: !!userId, refetchOnWindowFocus: true, // Function support for lazy initialData resolution initialData: () => ({ id: "", name: "Loading..." }), // Optional queryKey allows cache deduplication across components queryKey: ["user", { id: userId }], }); if (isFetching && !isRefetching) return <p>Loading...</p>; if (error) return <p>Error: {error.message}</p>; if (isEmpty) return <p>No user profiles found.</p>; return ( <div> <h1>{data?.name}</h1> {isRefetching && <p>Updating in background...</p>} <button onClick={() => refetch()}>Refresh Data</button> <button onClick={() => reset()}>Reset State</button> </div> ); }

Configuration Options

The useQuery hook accepts two arguments:

  1. proc: An async procedure function returning a [data, error] tuple.
  2. options: An optional configuration object (UseQueryOpts):
OptionTypeDefaultDescription
queryKeyunknown[]Unique array key for cache identification and deduplication.
initialDatadata | (() => data)Pre-populates cache on mount. Supports lazy evaluation functions.
enabledbooleantrueSet to false to disable automatic fetching on mount.
staleTimenumber | string0Time in milliseconds (or string window e.g., "5m") before data is considered stale.
gcTimenumber | string5 * 60 * 1000Time in milliseconds (or string window) before unused cache data is garbage collected.
refetchOnMountboolean | "always"trueRefetch on mount if stale (true), unconditionally ("always"), or disable mounting refetches (false).
refetchOnWindowFocusbooleanfalseAutomatically refetch when the window regains focus.
refetchOnReconnectboolean | "always"trueRefetch when network connection is restored.
refetchIntervalnumber0Time in milliseconds for automatic background polling.
unwrapbooleanfalseSet to true to return the nested data field of the RPC response directly.
select(data) => selectDataTransform the query response before returning it to the component.
onSuccess(data) => voidCallback run on successful data fetch.
onError(error) => voidCallback run when the procedure encounters an error.
onSettled(data, error) => voidCallback run when a query completes (success or failure).

Returned Properties

The hook returns the following control and state properties (QueryResult):

PropertyTypeDescription
dataTDataThe fetched (and optionally transformed/unwrapped) query data, or undefined if loading and no initialData is present.
errorErrorResponse | undefinedThe error object if the query failed.
isFetchingbooleanIndicates if a query fetch is currently in progress.
isRefetchingbooleanIndicates if a background refresh of the existing cached data is in progress.
isSuccessbooleanTrue if the query resolved successfully.
isErrorbooleanTrue if the query failed.
isFetchedbooleanTrue if the query has successfully resolved at least once.
isEmptybooleanTrue if the query resolved successfully and the data is empty (e.g. null, undefined, or []).
refetch() => Promise<TData>Triggers a manual refetch of the data.
reset() => voidResets the hook state back to the configured initialData.

Lazy initialData

The initialData option supports functions for lazy evaluation, preventing unnecessary computations during component render passes:

initialData: () => computeDefaultPayload();

Smart queryKey Object Serialization

When providing a custom queryKey array, Actyx RPC automatically detects and serializes nested objects (e.g., filter payloads) using JSON.stringify, ensuring deep comparison cache matching works out-of-the-box:

// Evaluates internally as: "user|{\"id\":\"123\",\"org\":\"explita\"}" queryKey: ["user", { id: "123", org: "explita" }];

Automatic Response Unwrapping

If your procedures wrap return shapes inside payload keys (e.g. returning { data: ... }), set unwrap: true to return the nested payload directly:

const { data } = useQuery(getSettings, { unwrap: true, // Strips away wrapper structure automatically initialData: { name: "Default Company", branches: [] }, });

useSuspenseQuery

For applications leveraging React Suspense boundaries:

import { useSuspenseQuery } from "@explita/actyx-rpc/react"; import { Suspense } from "react"; function TodoList() { const { data: todos } = useSuspenseQuery(() => getTodos(), { queryKey: ["todos"], }); return ( <ul> {todos.map((todo) => ( <li key={todo.id}>{todo.text}</li> ))} </ul> ); } export default function Page() { return ( <Suspense fallback={<div>Loading todos...</div>}> <TodoList /> </Suspense> ); }
Last updated on