Hybrid DataTable

Client-side fetching with TanStack Query + server-side operations. State in React, data from mock service.

Real API Adaptation

Replace the mock service with your HTTP client:

const { data } = useQuery({
  queryKey: ["users", query],
  queryFn: async () => {
    const params = new URLSearchParams({
      page: query.page.toString(),
      pageSize: query.pageSize.toString(),
      ...(query.sortBy && { sortBy: query.sortBy }),
      ...(query.search && { search: query.search }),
    });
    const res = await fetch(`/api/users?${params}`);
    return res.json(); // Returns TableResult<DemoUser>
  },
});

Current Query

Fetching
{
  "page": 0,
  "pageSize": 10
}

Users

Loading...

Loading users...

Code Pattern

State Management

// Table state in React
const [pagination, setPagination] = useState({
  pageIndex: 0,
  pageSize: 10,
});
const [sorting, setSorting] = useState([]);
const [columnFilters, setColumnFilters] = useState([]);
const [globalFilter, setGlobalFilter] = useState("");

// Build query from state
const query = buildTableQuery(
  pagination, sorting, columnFilters, globalFilter
);

TanStack Query

const { data, isLoading, isFetching } = useQuery({
  queryKey: ["demo-users", query],
  queryFn: () => fetchDemoTable(query),
  placeholderData: (prev) => prev, // Keep stale data
});

// State changes → query key changes → refetch
<BaseDataTable
  data={data?.items ?? []}
  manualPagination
  pageCount={data?.pageCount ?? -1}
  onPaginationChange={setPagination}
/>

When to use this pattern

Best for:

  • SPAs with client-side routing
  • When you need caching and background refetch
  • Complex state that doesn't need URL persistence
  • Real-time dashboards with polling/refetch intervals

Consider URL-based (server page) for:

  • SEO requirements (initial data in HTML)
  • Shareable/bookmarkable table states
  • Browser back/forward navigation support

Command Palette

Search for pages, contacts, deals, or perform quick actions