React Query (Remote) Example
This is just like the Remote Data Fetching Example, but react-query is used to simplify all the state management of the fetching and loading of data.
React Query is by far the best way to fetch remote data in React. It has features like caching, refetching, polling, pagination, and more that work together very well with table logic as seen in this example.
Also, be sure to check out the Virtualized Example, which shows off the use of another TanStack library, React Virtual, to render thousands of rows at once while still maintaining great performance.
First Name | Last Name | Address | State | Phone Number |
---|---|---|---|---|
10
0-0 of 0
1import { useMemo, useState } from 'react';2import {3 MaterialReactTable,4 type MRT_ColumnDef,5 type MRT_ColumnFiltersState,6 type MRT_PaginationState,7 type MRT_SortingState,8} from 'material-react-table';9import { IconButton, Tooltip } from '@mui/material';10import RefreshIcon from '@mui/icons-material/Refresh';11import {12 QueryClient,13 QueryClientProvider,14 keepPreviousData,15 useQuery,16} from '@tanstack/react-query';1718type UserApiResponse = {19 data: Array<User>;20 meta: {21 totalRowCount: number;22 };23};2425type User = {26 firstName: string;27 lastName: string;28 address: string;29 state: string;30 phoneNumber: string;31};3233const Example = () => {34 const [columnFilters, setColumnFilters] = useState<MRT_ColumnFiltersState>(35 [],36 );37 const [globalFilter, setGlobalFilter] = useState('');38 const [sorting, setSorting] = useState<MRT_SortingState>([]);39 const [pagination, setPagination] = useState<MRT_PaginationState>({40 pageIndex: 0,41 pageSize: 10,42 });4344 const { data, isError, isRefetching, isLoading, refetch } =45 useQuery<UserApiResponse>({46 queryKey: [47 'table-data',48 columnFilters, //refetch when columnFilters changes49 globalFilter, //refetch when globalFilter changes50 pagination.pageIndex, //refetch when pagination.pageIndex changes51 pagination.pageSize, //refetch when pagination.pageSize changes52 sorting, //refetch when sorting changes53 ],54 queryFn: async () => {55 const fetchURL = new URL(56 '/api/data',57 process.env.NODE_ENV === 'production'58 ? 'https://www.material-react-table.com'59 : 'http://localhost:3000',60 );61 fetchURL.searchParams.set(62 'start',63 `${pagination.pageIndex * pagination.pageSize}`,64 );65 fetchURL.searchParams.set('size', `${pagination.pageSize}`);66 fetchURL.searchParams.set(67 'filters',68 JSON.stringify(columnFilters ?? []),69 );70 fetchURL.searchParams.set('globalFilter', globalFilter ?? '');71 fetchURL.searchParams.set('sorting', JSON.stringify(sorting ?? []));7273 const response = await fetch(fetchURL.href);74 const json = (await response.json()) as UserApiResponse;75 return json;76 },77 placeholderData: keepPreviousData,78 });7980 const columns = useMemo<MRT_ColumnDef<User>[]>(81 () => [82 {83 accessorKey: 'firstName',84 header: 'First Name',85 },86 {87 accessorKey: 'lastName',88 header: 'Last Name',89 },90 {91 accessorKey: 'address',92 header: 'Address',93 },94 {95 accessorKey: 'state',96 header: 'State',97 },98 {99 accessorKey: 'phoneNumber',100 header: 'Phone Number',101 },102 ],103 [],104 );105106 return (107 <MaterialReactTable108 columns={columns}109 data={data?.data ?? []} //data is undefined on first render110 initialState={{ showColumnFilters: true }}111 manualFiltering112 manualPagination113 manualSorting114 muiToolbarAlertBannerProps={115 isError116 ? {117 color: 'error',118 children: 'Error loading data',119 }120 : undefined121 }122 onColumnFiltersChange={setColumnFilters}123 onGlobalFilterChange={setGlobalFilter}124 onPaginationChange={setPagination}125 onSortingChange={setSorting}126 renderTopToolbarCustomActions={() => (127 <Tooltip arrow title="Refresh Data">128 <IconButton onClick={() => refetch()}>129 <RefreshIcon />130 </IconButton>131 </Tooltip>132 )}133 rowCount={data?.meta?.totalRowCount ?? 0}134 state={{135 columnFilters,136 globalFilter,137 isLoading,138 pagination,139 showAlertBanner: isError,140 showProgressBars: isRefetching,141 sorting,142 }}143 />144 );145};146147const queryClient = new QueryClient();148149const ExampleWithReactQueryProvider = () => (150 //App.tsx or AppProviders file151 <QueryClientProvider client={queryClient}>152 <Example />153 </QueryClientProvider>154);155156export default ExampleWithReactQueryProvider;157
View Extra Storybook Examples