Hooks
useRead
Fetch data with automatic caching and triggering
Fetch data with automatic caching. Auto-fetches on mount.
Basic Usage
function UserList() {
const { data, loading, error, trigger } = useRead(
(api) => api("users").GET()
);
if (loading) return <div>Loading...</div>;
if (error) return <div>Error: {error.message}</div>;
return (
<ul>
{data?.map((user) => <li key={user.id}>{user.name}</li>)}
</ul>
);
}With Query Parameters
const { data, input } = useRead(
(api) => api("users").GET({ query: { page: 1, limit: 10 } }),
{
enabled: isReady,
tags: ["all", "custom-tag"],
}
);Tag Modes
// Mode only - 'all' generates full hierarchy
useRead((api) => api("users/:id/posts").GET({ params: { id: "123" } }), {
tags: "all", // ['users', 'users/123', 'users/123/posts']
});
// Mode only - 'self' generates only exact path
useRead((api) => api("users/:id/posts").GET({ params: { id: "123" } }), {
tags: "self", // ['users/123/posts']
});
// Mode only - 'none' generates no tags
useRead((api) => api("posts").GET(), { tags: "none" }); // []
// Custom tags only - replaces auto-generated tags
useRead((api) => api("posts").GET(), {
tags: ["custom", "dashboard"], // ['custom', 'dashboard']
});
// Mode + custom tags - 'all' mode combined with custom tags
useRead((api) => api("users/:id/posts").GET({ params: { id: "123" } }), {
tags: ["all", "dashboard"], // ['users', 'users/123', 'users/123/posts', 'dashboard']
});
// Mode + custom tags - 'self' mode combined with custom tags
useRead((api) => api("users/:id/posts").GET({ params: { id: "123" } }), {
tags: ["self", "dashboard"], // ['users/123/posts', 'dashboard']
});Options
| Option | Type | Default | Description |
|---|---|---|---|
enabled | boolean | true | Whether to fetch automatically |
tags | 'all' | 'self' | 'none' | string[] | 'all' | Tag mode or custom tags |
| + plugin options | - | - | Options from installed plugins |
Returns
| Property | Type | Description |
|---|---|---|
data | TData | undefined | Response data |
error | TError | undefined | Error if request failed |
loading | boolean | True during initial load |
fetching | boolean | True during any fetch |
trigger | (options?) => Promise | Manually trigger fetch with optional overrides |
abort | () => void | Abort current request |
input | object | The request input (query, body, params) |
meta | object | Plugin-provided metadata |
Trigger with Override Options
The trigger function accepts optional parameters to override the request:
const { data, trigger } = useRead((api) =>
api("users/:id").GET({ params: { id: "1" } })
);
// Refetch with same params
trigger();
// Fetch with different params
trigger({ params: { id: "2" } });
// Override query parameters
trigger({ query: { include: "profile" } });
// Force refetch (bypass cache)
trigger({ force: true });
// Combine overrides
trigger({ params: { id: "3" }, query: { include: "posts" }, force: true });You should avoid using custom options with
triggeras much as possible. Most of the time, you can achieve the same effect by changing theenabledand input parameters in the initial request.
Trigger Options
| Option | Type | Default | Description |
|---|---|---|---|
params | object | - | Override URL path parameters |
query | object | - | Override query string parameters |
body | unknown | - | Override request body |
force | boolean | false | Bypass cache and force fresh fetch |
On-Demand Fetching
For cases where you don't want to fetch on mount (like download or print), use enabled: false and call trigger manually:
function DownloadReport() {
const { data, loading, trigger } = useRead(
(api) => api("reports/:id").GET({ params: { id: "" } }), // placeholder
{ enabled: false }
);
const handleDownload = async (reportId: string) => {
const { data } = await trigger({ params: { id: reportId } });
if (data) {
// Process the downloaded report
downloadFile(data.url, data.filename);
}
};
return (
<div>
<button onClick={() => handleDownload("monthly")} disabled={loading}>
Download Monthly Report
</button>
<button onClick={() => handleDownload("yearly")} disabled={loading}>
Download Yearly Report
</button>
</div>
);
}