Shadcn React Table

Search documentation

Search the docs

Loading state

Pass isLoading: true to render skeleton rows and a progress bar in place of the data. Flip it back to false to reveal the real rows. This is especially useful with server-side data, where you toggle it around each fetch.

Loading stateSkeleton rows + progress bar; toggle to compare.
GitHub
Loading…
ID
AvaThompsonOwnerEngineeringactive22$45,000Jan 2, 2023
0%
LiamNguyenAdminMarketinginactive25$47,137Jan 13, 2023
9%
NoahSilvaEditorDesignpending28$49,274Jan 24, 2023
18%
EmmaCarterViewerSalesactive31$51,411Feb 4, 2023
27%
OliviaRossiOwnerSupportinactive34$53,548Feb 15, 2023
36%
WilliamWalkerAdminEngineeringpending37$55,685Feb 26, 2023
45%
SophiaPatelEditorMarketingactive40$57,822Mar 9, 2023
54%
JamesMullerViewerDesigninactive43$59,959Mar 20, 2023
63%
IsabellaParkOwnerSalespending46$62,096Mar 31, 2023
72%
LucasReyesAdminSupportactive49$64,233Apr 11, 2023
81%
$4,120,536
Rows per page
1–10 of 48

Usage

Drive isLoading from your own state and toggle it however you like — here with useState and a button in renderTopToolbarCustomActions:

tsx
const [isLoading, setIsLoading] = useState(false)

const table = useDataTable({
  data,
  columns,
  getRowId: (row) => row.id,
  isLoading,
  renderTopToolbarCustomActions: () => (
    <Button
      variant="outline"
      size="sm"
      onClick={() => setIsLoading((prev) => !prev)}
    >
      {isLoading ? "Show data" : "Show loading"}
    </Button>
  ),
})

return <DataTable table={table} />
Empty stateA custom message and action when there are no rows.
GitHub
ID
No people yetInvite your team to see them here.
$0
Rows per page
0–0 of 0

Reading the state

You can read the current value back from the table instance:

tsx
if (table.dataTable.isLoading) {
  // skeletons + progress bar are showing
}

Pairs well with server-side data

Set isLoading to true before a request and back to false when it resolves so users always see the skeletons while new pages or filtered results load.

Saving state

For an in-flight mutation (rather than an initial load), set isSaving: true. It shows the progress bar without replacing rows with skeletons, so the current data stays visible while the save runs.

tsx
useDataTable({ data, columns, getRowId: (row) => row.id, isSaving })

Choosing which affordances show

isLoading turns on three affordances together; override any of them independently:

  • showProgressBars — the top progress bar (default isLoading || isSaving).
  • showSkeletons — skeleton rows while the body is empty (default isLoading). The skeletons are drawn in each column, at the column's width and pinning, with bars of varying length. Pass showSkeletons: true to cover rows already shown too — handy while refetching — instead of dimming them. Style the bars with slotProps.skeleton.
  • showLoadingOverlay — a dimming overlay over existing rows (default isLoading).
tsx
useDataTable({
  data,
  columns,
  getRowId: (row) => row.id,
  isLoading,
  showSkeletons: false, // keep rows visible, just dim + show the progress bar
})
Loading skeletonsSkeletons for the first load and over rows while refetching.
GitHub
ID
AvaThompsonOwnerEngineeringactive22$45,000Jan 2, 2023
0%
LiamNguyenAdminMarketinginactive25$47,137Jan 13, 2023
9%
NoahSilvaEditorDesignpending28$49,274Jan 24, 2023
18%
EmmaCarterViewerSalesactive31$51,411Feb 4, 2023
27%
OliviaRossiOwnerSupportinactive34$53,548Feb 15, 2023
36%
WilliamWalkerAdminEngineeringpending37$55,685Feb 26, 2023
45%
SophiaPatelEditorMarketingactive40$57,822Mar 9, 2023
54%
JamesMullerViewerDesigninactive43$59,959Mar 20, 2023
63%
$4,120,536
Rows per page
1–8 of 48

Relevant options

PropTypeDefaultDescription
isLoading?booleanfalseShow the loading affordances (progress bar; skeletons when empty; a dimming overlay over existing rows). Toggle each independently below.
isSaving?booleanfalseShow the progress bar for an in-flight save/mutation. Defaults the progress bar on without replacing rows with skeletons.
showProgressBars?boolean—Show the top progress bar. Default: `isLoading || isSaving`.
showSkeletons?boolean—Show skeleton rows while the body is empty. Default: `isLoading`. Passing `true` also covers rows already shown with skeletons (e.g. while refetching), instead of dimming them.
showLoadingOverlay?boolean—Dim existing rows with an overlay while loading. Default: `isLoading`.