useQuery
Call a server-side query function and return its result. The query runs once on mount and can be manually refetched.
Signature
const { data, isLoading, error, refetch } = useQuery<T>(functionName: string, args?: Record<string, unknown>);
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
functionName | string | Yes | Name of the exported server query function |
args | Record<string, unknown> | No | Arguments to pass to the query function |
Return value
| Property | Type | Description |
|---|---|---|
data | T | null | Query result, or null while loading or on error |
isLoading | boolean | true while the query is in flight |
error | string | null | Error message if the query failed |
refetch | () => void | Call to re-run the query |
Example
Define the server function in server/functions.ts:
// server/functions.ts
import { queryRows } from "@zaflun/lumio-sdk/server";
export const getRules = queryRows("rules");
Use it in a surface:
import { useQuery, List, Text, Button } from "@zaflun/lumio-sdk";
function RuleList() {
const { data: rules, isLoading, error, refetch } = useQuery("getRules");
if (isLoading) return <Text content="Loading..." variant="muted" />;
if (error) return <Text content={`Error: ${error}`} variant="muted" />;
return (
<>
<Button label="Refresh" onClick={refetch} />
<List
items={(rules ?? []).map((rule) => ({
id: rule.id,
label: rule.text,
}))}
/>
</>
);
}
Example with arguments
// server/functions.ts
import { queryRows, filter, arg } from "@zaflun/lumio-sdk/server";
export const getRulesByStatus = queryRows("rules", {
filter: filter("revealed", "=", arg("revealed")),
});
const { data: revealedRules } = useQuery("getRulesByStatus", { revealed: true });
const { data: hiddenRules } = useQuery("getRulesByStatus", { revealed: false });
Auto-refetch on storage change
useQuery does not auto-refetch when storage changes. After a mutation, call refetch() manually:
const { data, refetch } = useQuery("getRules");
const { mutate: addRule } = useMutation("addRule");
const handleAdd = async () => {
await addRule({ text: "New rule" });
refetch(); // manually refresh the list
};
Notes
useQueryruns on mount automatically — no need to call anything to initiate the first load- The query is rate limited to 100 calls per minute per installation
- Queries are read-only — use
useMutationfor write operations - Multiple calls to
useQuerywith the samefunctionNameandargsare not deduplicated — if you need shared data, lift the state up