MRT logoMaterial React Table

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.


Demo

Open Code SandboxOpen on GitHub

Rows per page

0-0 of 0

Source Code

1import React, { FC, useMemo, useState } from 'react';
2import MaterialReactTable, { MRT_ColumnDef } from 'material-react-table';
3import type {
4 ColumnFiltersState,
5 PaginationState,
6 SortingState,
7} from '@tanstack/react-table';
8import {
9 QueryClient,
10 QueryClientProvider,
11 useQuery,
12} from '@tanstack/react-query';
13import axios from 'axios';
14
15type UserApiResponse = {
16 data: Array<User>;
17 meta: {
18 totalRowCount: number;
19 };
20};
21
22type User = {
23 firstName: string;
24 lastName: string;
25 address: string;
26 state: string;
27 phoneNumber: string;
28};
29
30const Example: FC = () => {
31 const [columnFilters, setColumnFilters] = useState<ColumnFiltersState>([]);
32 const [globalFilter, setGlobalFilter] = useState('');
33 const [sorting, setSorting] = useState<SortingState>([]);
34 const [pagination, setPagination] = useState<PaginationState>({
35 pageIndex: 0,
36 pageSize: 10,
37 });
38
39 const { data, isError, isFetching, isLoading } = useQuery<UserApiResponse>(
40 [
41 'table-data',
42 columnFilters,
43 globalFilter,
44 pagination.pageIndex,
45 pagination.pageSize,
46 sorting,
47 ],
48 async () => {
49 const url = new URL(
50 '/api/data',
51 process.env.NODE_ENV === 'production'
52 ? 'https://www.material-react-table.com'
53 : 'http://localhost:3000',
54 );
55 url.searchParams.set(
56 'start',
57 `${pagination.pageIndex * pagination.pageSize}`,
58 );
59 url.searchParams.set('size', `${pagination.pageSize}`);
60 url.searchParams.set('filters', JSON.stringify(columnFilters ?? []));
61 url.searchParams.set('globalFilter', globalFilter ?? '');
62 url.searchParams.set('sorting', JSON.stringify(sorting ?? []));
63
64 const { data: axiosData } = await axios.get(url.href);
65 return axiosData;
66 },
67 { keepPreviousData: true },
68 );
69
70 const columns = useMemo<MRT_ColumnDef<User>[]>(
71 () => [
72 {
73 accessorKey: 'firstName',
74 header: 'First Name',
75 },
76 {
77 accessorKey: 'lastName',
78 header: 'Last Name',
79 },
80 {
81 accessorKey: 'address',
82 header: 'Address',
83 },
84 {
85 accessorKey: 'state',
86 header: 'State',
87 },
88 {
89 accessorKey: 'phoneNumber',
90 header: 'Phone Number',
91 },
92 ],
93 [],
94 );
95
96 return (
97 <MaterialReactTable
98 columns={columns}
99 data={data?.data ?? []}
100 initialState={{ showColumnFilters: true }}
101 manualFiltering
102 manualPagination
103 manualSorting
104 muiToolbarAlertBannerProps={
105 isError
106 ? {
107 color: 'error',
108 children: 'Error loading data',
109 }
110 : undefined
111 }
112 onColumnFiltersChange={setColumnFilters}
113 onGlobalFilterChange={setGlobalFilter}
114 onPaginationChange={setPagination}
115 onSortingChange={setSorting}
116 rowCount={data?.meta?.totalRowCount ?? 0}
117 state={{
118 columnFilters,
119 globalFilter,
120 isLoading,
121 pagination,
122 showAlertBanner: isError,
123 showProgressBars: isFetching,
124 sorting,
125 }}
126 />
127 );
128};
129
130const queryClient = new QueryClient();
131
132const ExampleWithReactQueryProvider = () => (
133 <QueryClientProvider client={queryClient}>
134 <Example />
135 </QueryClientProvider>
136);
137
138export default ExampleWithReactQueryProvider;
139

View Extra Storybook Examples