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(
55 '/api/data',
56 process.env.NODE_ENV === 'production'
57 ? 'https://www.material-react-table.com'
58 : 'http://localhost:3000',
59 );
60 url.searchParams.set(
61 'start',
62 `${pagination.pageIndex * pagination.pageSize}`,
63 );
64 url.searchParams.set('size', `${pagination.pageSize}`);
65 url.searchParams.set('filters', JSON.stringify(columnFilters ?? []));
66 url.searchParams.set('globalFilter', globalFilter ?? '');
67 url.searchParams.set('sorting', JSON.stringify(sorting ?? []));
68
69 try {
70 const response = await fetch(url.href);
71 const json = (await response.json()) as UserApiResponse;
72 setData(json.data);
73 setRowCount(json.meta.totalRowCount);
74 } catch (error) {
75 setIsError(true);
76 console.error(error);
77 return;
78 }
79 setIsError(false);
80 setIsLoading(false);
81 setIsRefetching(false);
82 };
83 fetchData();
84 // eslint-disable-next-line react-hooks/exhaustive-deps
85 }, [
86 columnFilters, //re-fetch when column filters change
87 globalFilter, //re-fetch when global filter changes
88 pagination.pageIndex, //re-fetch when page index changes
89 pagination.pageSize, //re-fetch when page size changes
90 sorting, //re-fetch when sorting changes
91 ]);
92
93 const columns = useMemo<MRT_ColumnDef<User>[]>(
94 () => [
95 {
96 accessorKey: 'firstName',
97 header: 'First Name',
98 },
99 //column definitions...
117 ],
118 [],
119 );
120
121 const table = useMaterialReactTable({
122 columns,
123 data,
124 enableRowSelection: true,
125 getRowId: (row) => row.phoneNumber,
126 initialState: { showColumnFilters: true },
127 manualFiltering: true,
128 manualPagination: true,
129 manualSorting: true,
130 muiToolbarAlertBannerProps: isError
131 ? {
132 color: 'error',
133 children: 'Error loading data',
134 }
135 : undefined,
136 onColumnFiltersChange: setColumnFilters,
137 onGlobalFilterChange: setGlobalFilter,
138 onPaginationChange: setPagination,
139 onSortingChange: setSorting,
140 rowCount,
141 state: {
142 columnFilters,
143 globalFilter,
144 isLoading,
145 pagination,
146 showAlertBanner: isError,
147 showProgressBars: isRefetching,
148 sorting,
149 },
150 });
151
152 return <MaterialReactTable table={table} />;
153};
154
155export default Example;
156

View Extra Storybook Examples