Query Integration
Shared QueryClient architecture, invalidation, and refetch behavior
Use the same action catalog
The following complete example builds on the quick start and shared recipe files. The reference below explains individual options and integration fragments.
import type { TableActions } from "@/components/ui/yayaw-table/providers/table-provider";
import { productStore } from "../shared/store";
import { listRecords } from "./list-records";
import { viewActions } from "./view-actions";
export const editableActions: TableActions = {
views: viewActions,
list: (params) => listRecords(productStore.rows, params),
update: (id, patch) => Promise.resolve(productStore.update(id, patch)),
bulkUpdate: (ids, patch) =>
Promise.resolve(productStore.bulkUpdate(ids, patch)),
};
export const getEditableActions = (tableType: string) =>
tableType === "products" ? editableActions : undefined;import type { TableActions } from "@/components/ui/yayaw-table-vue/types";
import { productStore } from "../shared/store";
import { listRecords } from "./list-records";
import { viewActions } from "./view-actions";
export const editableActions: TableActions = {
views: viewActions,
list: (params) => listRecords(productStore.rows, params),
update: (id, patch) => Promise.resolve(productStore.update(id, patch)),
bulkUpdate: (ids, patch) =>
Promise.resolve(productStore.bulkUpdate(ids, patch)),
};
export const getEditableActions = (tableType: string) =>
tableType === "products" ? editableActions : undefined;Query Integration
The React edition requires a shared QueryClient. The React rules below do not apply to Vue; its cache contract is described at the end of this page.
There is no implicit internal QueryClient anymore. This avoids isolated caches where invalidations did not refresh table data.
Required architecture
Use exactly one app-level client:
"use client";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { DataTable } from "@/components/ui/yayaw-table";
import { getTableActions, getTableConfig } from "./table-config";
const queryClient = new QueryClient();
export default function ProductsPage() {
return (
<QueryClientProvider client={queryClient}>
<DataTable
tableType="products"
getTableConfig={getTableConfig}
getTableActions={getTableActions}
/>
</QueryClientProvider>
);
}What invalidate/refetch should do
When row or bulk actions succeed, Yayaw Table invalidates:
["tableData", tableId]Then active queries refetch and the table updates with fresh server data.
Correct invalidation from custom code
When you run custom mutations outside Yayaw Table, invalidate the same key:
await queryClient.invalidateQueries({
queryKey: ["tableData", "products"],
});Guardrails added by Yayaw Table
If no QueryClient is available, Yayaw Table throws an explicit runtime error.
If both a provider and a
queryClientprop are set with different instances, Yayaw Table throws an explicit runtime error.Silent cache duplication is prevented.
Vue cache and mutation refresh
Vue creates a local Vue Query client by default and accepts a shared queryClient prop. Its keys start with ["yayaw-table", tableId]; React's ["tableData", tableId] keys are not interchangeable.
Built-in Vue mutations refresh the active list. Invalidating that active list also reloads it; invalidating only an aggregate or an older cached page does not. Explicit mutation refresh cancels a pending pre-mutation list request. If deletion empties the last server page, Vue requests the preceding valid page; local data shrinkage also clamps pagination.
Consumer-owned callbacks remain responsible for persistence and follow-up refresh unless their result contract explicitly requests library handling. See Bulk actions for callback results and selected-row behavior.
Complete exports and server page limits
Toolbar export retrieves every matching row with the query and visible-column order captured when it starts. Bulk export uses selected rows. Local data uses the same filters and sorting. Built-in CSV includes visible data columns in display order; custom export callbacks retain their signatures and precedence.
React and Vue share the page collector used for server export and select-all. Server caps do not truncate collection when meta.pageCount or meta.totalCount describes the complete result. Without metadata, a short page ends collection. A failed request, inconsistent empty page, or the 1,000-page limit produces an error instead of silently exporting partial results. Export remains disabled while pending and can be retried after failure.