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.
First Name | Last Name | Address | State | Phone Number | |
---|---|---|---|---|---|
No records to display |
10
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';1011type UserApiResponse = {12 data: Array<User>;13 meta: {14 totalRowCount: number;15 };16};1718type User = {19 firstName: string;20 lastName: string;21 address: string;22 state: string;23 phoneNumber: string;24};2526const Example = () => {27 //data and fetching state28 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);3334 //table state35 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 });4445 //if you want to avoid useEffect, look at the React Query example instead46 useEffect(() => {47 const fetchData = async () => {48 if (!data.length) {49 setIsLoading(true);50 } else {51 setIsRefetching(true);52 }5354 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 ?? []));6364 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-deps80 }, [81 columnFilters, //re-fetch when column filters change82 globalFilter, //re-fetch when global filter changes83 pagination.pageIndex, //re-fetch when page index changes84 pagination.pageSize, //re-fetch when page size changes85 sorting, //re-fetch when sorting changes86 ]);8788 const columns = useMemo<MRT_ColumnDef<User>[]>(89 () => [90 {91 accessorKey: 'firstName',92 header: 'First Name',93 },94 //column definitions...112 ],113 [],114 );115116 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: isError126 ? {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 });146147 return <MaterialReactTable table={table} />;148};149150export default Example;151
View Extra Storybook Examples