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
0-0 of 0
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(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 ?? []));6869 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-deps85 }, [86 columnFilters, //re-fetch when column filters change87 globalFilter, //re-fetch when global filter changes88 pagination.pageIndex, //re-fetch when page index changes89 pagination.pageSize, //re-fetch when page size changes90 sorting, //re-fetch when sorting changes91 ]);9293 const columns = useMemo<MRT_ColumnDef<User>[]>(94 () => [95 {96 accessorKey: 'firstName',97 header: 'First Name',98 },99 //column definitions...117 ],118 [],119 );120121 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: isError131 ? {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 });151152 return <MaterialReactTable table={table} />;153};154155export default Example;156
View Extra Storybook Examples