MRT logoMaterial React Table

Remote Data 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 TanStack 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.


Rows per page

0-0 of 0

Source Code

1import React, { useEffect, useMemo, useState } from 'react';
2import MaterialReactTable from 'material-react-table';
3
4const Example = () => {
5 //data and fetching state
6 const [data, setData] = useState([]);
7 const [isError, setIsError] = useState(false);
8 const [isLoading, setIsLoading] = useState(false);
9 const [isRefetching, setIsRefetching] = useState(false);
10 const [rowCount, setRowCount] = useState(0);
11
12 //table state
13 const [columnFilters, setColumnFilters] = useState([]);
14 const [globalFilter, setGlobalFilter] = useState('');
15 const [sorting, setSorting] = useState([]);
16 const [pagination, setPagination] = useState({
17 pageIndex: 0,
18 pageSize: 10,
19 });
20
21 //if you want to avoid useEffect, look at the React Query example instead
22 useEffect(() => {
23 const fetchData = async () => {
24 if (!data.length) {
25 setIsLoading(true);
26 } else {
27 setIsRefetching(true);
28 }
29
30 const url = new URL(
31 '/api/data',
32 process.env.NODE_ENV === 'production'
33 ? 'https://www.material-react-table.com'
34 : 'http://localhost:3000',
35 );
36 url.searchParams.set(
37 'start',
38 `${pagination.pageIndex * pagination.pageSize}`,
39 );
40 url.searchParams.set('size', `${pagination.pageSize}`);
41 url.searchParams.set('filters', JSON.stringify(columnFilters ?? []));
42 url.searchParams.set('globalFilter', globalFilter ?? '');
43 url.searchParams.set('sorting', JSON.stringify(sorting ?? []));
44
45 try {
46 const response = await fetch(url.href);
47 const json = await response.json();
48 setData(json.data);
49 setRowCount(json.meta.totalRowCount);
50 } catch (error) {
51 setIsError(true);
52 console.error(error);
53 return;
54 }
55 setIsError(false);
56 setIsLoading(false);
57 setIsRefetching(false);
58 };
59 fetchData();
60 // eslint-disable-next-line react-hooks/exhaustive-deps
61 }, [
62 columnFilters,
63 globalFilter,
64 pagination.pageIndex,
65 pagination.pageSize,
66 sorting,
67 ]);
68
69 const columns = useMemo(
70 () => [
71 {
72 accessorKey: 'firstName',
73 header: 'First Name',
74 },
75 //column definitions...
93 ],
94 [],
95 );
96
97 return (
98 <MaterialReactTable
99 columns={columns}
100 data={data}
101 enableRowSelection
102 getRowId={(row) => row.phoneNumber}
103 initialState={{ showColumnFilters: true }}
104 manualFiltering
105 manualPagination
106 manualSorting
107 muiToolbarAlertBannerProps={
108 isError
109 ? {
110 color: 'error',
111 children: 'Error loading data',
112 }
113 : undefined
114 }
115 onColumnFiltersChange={setColumnFilters}
116 onGlobalFilterChange={setGlobalFilter}
117 onPaginationChange={setPagination}
118 onSortingChange={setSorting}
119 rowCount={rowCount}
120 state={{
121 columnFilters,
122 globalFilter,
123 isLoading,
124 pagination,
125 showAlertBanner: isError,
126 showProgressBars: isRefetching,
127 sorting,
128 }}
129 />
130 );
131};
132
133export default Example;
134

View Extra Storybook Examples