useServerQuery
Wraps a server function for query-style (read) usage. Automatically executes on mount and re-fetches when the cache key changes. Supports stale-time caching and manual refetching.
Import
import { useServerQuery } from "catmint/hooks";
Signature
function useServerQuery<TInput, TOutput>(
fn: (input: TInput) => Promise<TOutput>,
opts: ServerQueryOptions<TInput>,
): ServerQueryState<TOutput>;
interface ServerQueryOptions<TInput> {
input: TInput;
key?: unknown[];
enabled?: boolean;
staleTime?: number;
}
interface ServerQueryState<TOutput> {
data: TOutput | undefined;
error: Error | undefined;
loading: boolean;
refetch: () => Promise<void>;
}
Parameters
| Parameter | Type | Required | Description |
|---|
fn | (input: TInput) => Promise<TOutput> | Yes | A server function to call as a query. |
opts | ServerQueryOptions<TInput> | Yes | Query configuration (see below). |
ServerQueryOptions
| Property | Type | Required | Description |
|---|
input | TInput | Yes | The input to pass to the server function. |
key | unknown[] | No | Cache key array. When the serialized key changes, the query re-fetches. Also used for stale-time caching. |
enabled | boolean | No | Whether the query should auto-execute. Defaults to true. Set to false to defer execution. |
staleTime | number | No | Time in milliseconds that cached data is considered fresh. While fresh, the query returns cached data without re-fetching. |
Return Value
| Property | Type | Description |
|---|
data | TOutput | undefined | The query result, or undefined if not yet loaded. |
error | Error | undefined | The most recent error, or undefined. |
loading | boolean | true while the query is in flight. |
refetch | () => Promise<void> | Manually re-fetch the data, bypassing the stale-time cache. |
Examples
Basic query
// UserProfile.client.tsx
import { useServerQuery } from "catmint/hooks";
import { getUser } from "./queries";
function UserProfile({ userId }: { userId: string }) {
const { data, loading, error } = useServerQuery(getUser, {
input: { id: userId },
key: [userId],
});
if (loading) return <p>Loading...</p>;
if (error) return <p>Error: {error.message}</p>;
if (!data) return null;
return <h1>{data.name}</h1>;
}
With stale-time caching
const { data } = useServerQuery(getProducts, {
input: { category: "shoes" },
key: ["products", "shoes"],
staleTime: 60_000, // Cache for 1 minute
});
Conditional fetching
const { data } = useServerQuery(getOrderDetails, {
input: { orderId },
key: [orderId],
enabled: !!orderId, // Only fetch when orderId is available
});
Manual refetch
const { data, refetch } = useServerQuery(getNotifications, {
input: {},
key: ["notifications"],
});
return (
<div>
<button onClick={() => refetch()}>Refresh</button>
{data?.map((n) => (
<Notification key={n.id} {...n} />
))}
</div>
);
See Also