React Query (Remote) Example
This is just like the Remote Data Example, but react-query is used to simplify all the state management of the fetching and loading of data.
Also, be sure to check out the Virtualized Example, which shows off the use of another TanStack library, TanStack React Virtual, to render thousands of rows at once while still maintaining great performance.
First Name | Last Name | Address | State | Phone Number |
---|---|---|---|---|
1import React, { FC, useMemo, useState } from 'react';2import MaterialReactTable, { MRT_ColumnDef } from 'material-react-table';3import { IconButton, Tooltip } from '@mui/material';4import RefreshIcon from '@mui/icons-material/Refresh';5import type {6 ColumnFiltersState,7 PaginationState,8 SortingState,9} from '@tanstack/react-table';10import {11 QueryClient,12 QueryClientProvider,13 useQuery,14} from '@tanstack/react-query';1516type UserApiResponse = {17 data: Array<User>;18 meta: {19 totalRowCount: number;20 };21};2223type User = {24 firstName: string;25 lastName: string;26 address: string;27 state: string;28 phoneNumber: string;29};3031const Example: FC = () => {32 const [columnFilters, setColumnFilters] = useState<ColumnFiltersState>([]);33 const [globalFilter, setGlobalFilter] = useState('');34 const [sorting, setSorting] = useState<SortingState>([]);35 const [pagination, setPagination] = useState<PaginationState>({36 pageIndex: 0,37 pageSize: 10,38 });3940 const { data, isError, isFetching, isLoading, refetch } =41 useQuery<UserApiResponse>(42 [43 'table-data',44 columnFilters,45 globalFilter,46 pagination.pageIndex,47 pagination.pageSize,48 sorting,49 ],50 async () => {51 const url = new URL(52 '/api/data',53 process.env.NODE_ENV === 'production'54 ? 'https://www.material-react-table.com'55 : 'http://localhost:3000',56 );57 url.searchParams.set(58 'start',59 `${pagination.pageIndex * pagination.pageSize}`,60 );61 url.searchParams.set('size', `${pagination.pageSize}`);62 url.searchParams.set('filters', JSON.stringify(columnFilters ?? []));63 url.searchParams.set('globalFilter', globalFilter ?? '');64 url.searchParams.set('sorting', JSON.stringify(sorting ?? []));6566 const response = await fetch(url.href);67 const json = (await response.json()) as UserApiResponse;68 return json;69 },70 { keepPreviousData: true },71 );7273 const columns = useMemo<MRT_ColumnDef<User>[]>(74 () => [75 {76 accessorKey: 'firstName',77 header: 'First Name',78 },79 {80 accessorKey: 'lastName',81 header: 'Last Name',82 },83 {84 accessorKey: 'address',85 header: 'Address',86 },87 {88 accessorKey: 'state',89 header: 'State',90 },91 {92 accessorKey: 'phoneNumber',93 header: 'Phone Number',94 },95 ],96 [],97 );9899 return (100 <MaterialReactTable101 columns={columns}102 data={data?.data ?? []} //data is undefined on first render103 initialState={{ showColumnFilters: true }}104 manualFiltering105 manualPagination106 manualSorting107 muiToolbarAlertBannerProps={108 isError109 ? {110 color: 'error',111 children: 'Error loading data',112 }113 : undefined114 }115 onColumnFiltersChange={setColumnFilters}116 onGlobalFilterChange={setGlobalFilter}117 onPaginationChange={setPagination}118 onSortingChange={setSorting}119 renderTopToolbarCustomActions={() => (120 <Tooltip arrow title="Refresh Data">121 <IconButton onClick={() => refetch()}>122 <RefreshIcon />123 </IconButton>124 </Tooltip>125 )}126 rowCount={data?.meta?.totalRowCount ?? 0}127 state={{128 columnFilters,129 globalFilter,130 isLoading,131 pagination,132 showAlertBanner: isError,133 showProgressBars: isFetching,134 sorting,135 }}136 />137 );138};139140const queryClient = new QueryClient();141142const ExampleWithReactQueryProvider = () => (143 <QueryClientProvider client={queryClient}>144 <Example />145 </QueryClientProvider>146);147148export default ExampleWithReactQueryProvider;149
View Extra Storybook Examples