MRT logoMaterial React Table

Remote Data Fetching Example

You will most likely be using a remote data source for your table, which is fully supported. Here is an example of data being fetched from a remote server but also filtered, paginated, and sorted on the server.

Also, be sure to check out the React Query Example, which is very similar to this one, except it uses react-query to simplify much of the state management needed for fetching data, so that you don't need to fetch from a useEffect hook.

CRUD Examples
More Examples

Demo

Open StackblitzOpen Code SandboxOpen on GitHub

No records to display

0-0 of 0

Source Code

1import { useEffect, useMemo, useState } from 'react';
2import {
3 MaterialReactTable,
4 useMaterialReactTable,
5 type MRT_ColumnDef,
6 type MRT_ColumnFiltersState,
7 type MRT_PaginationState,
8 type MRT_SortingState,
9} from 'material-react-table';
10
11type UserApiResponse = {
12 data: Array<User>;
13 meta: {
14 totalRowCount: number;
15 };
16};
17
18type User = {
19 firstName: string;
20 lastName: string;
21 address: string;
22 state: string;
23 phoneNumber: string;
24};
25
26const Example = () => {
27 //data and fetching state
28 const [data, setData] = useState<User[]>([]);
29 const [isError, setIsError] = useState(false);
30 const [isLoading, setIsLoading] = useState(false);
31 const [isRefetching, setIsRefetching] = useState(false);
32 const [rowCount, setRowCount] = useState(0);
33
34 //table state
35 const [columnFilters, setColumnFilters] = useState<MRT_ColumnFiltersState>(
36 [],
37 );
38 const [globalFilter, setGlobalFilter] = useState('');
39 const [sorting, setSorting] = useState<MRT_SortingState>([]);
40 const [pagination, setPagination] = useState<MRT_PaginationState>({
41 pageIndex: 0,
42 pageSize: 10,
43 });
44
45 //if you want to avoid useEffect, look at the React Query example instead
46 useEffect(() => {
47 const fetchData = async () => {
48 if (!data.length) {
49 setIsLoading(true);
50 } else {
51 setIsRefetching(true);
52 }
53
54 const url = new URL('/api/data', location.origin);
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 try {
65 const response = await fetch(url.href);
66 const json = (await response.json()) as UserApiResponse;
67 setData(json.data);
68 setRowCount(json.meta.totalRowCount);
69 } catch (error) {
70 setIsError(true);
71 console.error(error);
72 return;
73 }
74 setIsError(false);
75 setIsLoading(false);
76 setIsRefetching(false);
77 };
78 fetchData();
79 // eslint-disable-next-line react-hooks/exhaustive-deps
80 }, [
81 columnFilters, //re-fetch when column filters change
82 globalFilter, //re-fetch when global filter changes
83 pagination.pageIndex, //re-fetch when page index changes
84 pagination.pageSize, //re-fetch when page size changes
85 sorting, //re-fetch when sorting changes
86 ]);
87
88 const columns = useMemo<MRT_ColumnDef<User>[]>(
89 () => [
90 {
91 accessorKey: 'firstName',
92 header: 'First Name',
93 },
94 //column definitions...
112 ],
113 [],
114 );
115
116 const table = useMaterialReactTable({
117 columns,
118 data,
119 enableRowSelection: true,
120 getRowId: (row) => row.phoneNumber,
121 initialState: { showColumnFilters: true },
122 manualFiltering: true,
123 manualPagination: true,
124 manualSorting: true,
125 muiToolbarAlertBannerProps: isError
126 ? {
127 color: 'error',
128 children: 'Error loading data',
129 }
130 : undefined,
131 onColumnFiltersChange: setColumnFilters,
132 onGlobalFilterChange: setGlobalFilter,
133 onPaginationChange: setPagination,
134 onSortingChange: setSorting,
135 rowCount,
136 state: {
137 columnFilters,
138 globalFilter,
139 isLoading,
140 pagination,
141 showAlertBanner: isError,
142 showProgressBars: isRefetching,
143 sorting,
144 },
145 });
146
147 return <MaterialReactTable table={table} />;
148};
149
150export default Example;
151

View Extra Storybook Examples