Filtering Data with Date Ranges in TanStack Table v8
TanStack Table v8 is a powerful and flexible data table library that provides a wide range of features, including advanced filtering capabilities. Filtering data by date ranges is a common requirement in many applications, and TanStack Table makes it easy to implement.
The Scenario
Let's say you have a table displaying a list of orders with a "createdAt" column containing date and time information. You want to allow users to filter this data based on a specific date range.
Original Code:
import { useTable, useFilters } from 'react-table';
const columns = [
{ Header: 'Order ID', accessor: 'id' },
{ Header: 'Created At', accessor: 'createdAt' },
// ... other columns
];
const data = [
// ... order data
];
function OrderTable() {
const { getTableProps, getTableBodyProps, headerGroups, rows, prepareRow } = useTable({
columns,
data,
}, useFilters);
return (
<table {...getTableProps()}>
<thead>
{headerGroups.map(headerGroup => (
<tr {...headerGroup.getHeaderGroupProps()}>
{headerGroup.headers.map(column => (
<th {...column.getHeaderProps()}>{column.render('Header')}</th>
))}
</tr>
))}
</thead>
<tbody {...getTableBodyProps()}>
{rows.map(row => {
prepareRow(row);
return (
<tr {...row.getRowProps()}>
{row.cells.map(cell => (
<td {...cell.getCellProps()}>{cell.render('Cell')}</td>
))}
</tr>
);
})}
</tbody>
</table>
);
}
Implementing Date Range Filtering
-
Adding a Date Range Filter Component:
Create a component for your date range filter. This could be a custom UI using date pickers or a pre-built library like React DatePicker. This component should emit two values:
startDate
andendDate
, representing the selected date range. -
Integrating the Filter Component:
In your table component, pass the
startDate
andendDate
values from your date range filter component to theuseFilters
hook. This will allow TanStack Table to apply the filter to your data. -
Defining the Filter Function:
You need to define a custom filter function that checks if the
createdAt
date falls within the specified range. This function should be passed touseFilters
as part of your table configuration.
import { useTable, useFilters } from 'react-table';
const columns = [
// ... same as before
];
const data = [
// ... same as before
];
function OrderTable() {
const [startDate, setStartDate] = useState(null); // State for the start date
const [endDate, setEndDate] = useState(null); // State for the end date
// ... other functions to handle date picker selection
const { getTableProps, getTableBodyProps, headerGroups, rows, prepareRow } = useTable({
columns,
data,
filterTypes: {
dateRange: (rows, id, filterValue) => {
return rows.filter(row => {
const createdAt = new Date(row.original.createdAt);
return createdAt >= filterValue.startDate && createdAt <= filterValue.endDate;
});
}
},
defaultColumn: {
Filter: ColumnFilter
}
}, useFilters);
return (
// ... same as before, with the date range filter component
);
}
function ColumnFilter({ column }) {
if (column.id === 'createdAt') {
return (
<div>
{/* Your Date Range Picker component here */}
<DatePicker
selected={startDate}
onChange={setStartDate}
startDate={startDate}
endDate={endDate}
selectsRange
/>
<DatePicker
selected={endDate}
onChange={setEndDate}
startDate={startDate}
endDate={endDate}
selectsRange
/>
</div>
);
}
return null;
}
Explanation and Additional Insights:
- The
filterTypes
object allows you to define custom filter functions for different column types. In this example, we defined adateRange
filter that takes thestartDate
andendDate
as input and filters the rows based on thecreatedAt
date. - The
defaultColumn
object in theuseTable
configuration allows you to define the default filter component for all columns. We've usedColumnFilter
to display a date range picker specifically for thecreatedAt
column. - You can customize the filter logic further to handle scenarios like excluding dates, filtering based on time intervals, or providing different filter options for the same column.
Benefits and Optimizations
- User-Friendly Filtering: Date range filtering provides a more intuitive and powerful way for users to interact with data compared to single date filters.
- Performance Optimization: By filtering the data directly in JavaScript, you avoid unnecessary network requests to fetch filtered data, leading to a faster user experience.
- Flexibility: TanStack Table's filter system allows for highly customizable filtering based on your application's specific needs.
Conclusion
TanStack Table v8 offers a robust and flexible framework for implementing custom filters, including date range filtering. By combining this with a user-friendly date picker component, you can provide a powerful and intuitive way for users to filter and analyze your data.