You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用TanStack Table v8实现字符串日期的范围过滤及输入框绑定

日期范围筛选器绑定与字符串日期过滤方案

一、绑定日期范围输入框

用React的useState管理开始和结束日期的状态,把两个原生日期输入框和状态做双向绑定,再将日期范围传给表格的过滤逻辑。示例代码如下:

import { useState } from 'react';
import { useReactTable, ColumnDef } from '@tanstack/react-table';

// 定义数据类型
type VTDATA = { date: string; value: string };

// 接口返回数据
const abc: VTDATA[] = [
  { date: '2023-12-8', value: 'mop' },
  { date: '2023-10-8', value: 'qrs' },
];

// 列配置
export const columns: ColumnDef<VTDATA>[] = [
  { accessorKey: "value", header: "Value" },
  { accessorKey: "date", header: "Date" },
];

export function DateFilterTable() {
  // 存储日期范围状态
  const [dateRange, setDateRange] = useState({ start: '', end: '' });

  // 创建表格实例,集成日期过滤
  const table = useReactTable({
    data: abc,
    columns,
    // 全局过滤函数处理日期范围
    globalFilterFn: (row, _, filterValue) => {
      const { start, end } = filterValue as typeof dateRange;
      if (!start && !end) return true;

      // 直接用字符串比较(YYYY-MM-DD格式支持字典序对比)
      const matchesStart = !start || row.getValue('date') >= start;
      const matchesEnd = !end || row.getValue('date') <= end;
      return matchesStart && matchesEnd;
    },
    globalFilter: dateRange,
  });

  return (
    <div>
      {/* 日期输入框绑定 */}
      <input
        type="date"
        value={dateRange.start}
        onChange={e => setDateRange(prev => ({ ...prev, start: e.target.value }))}
      />
      <span>至</span>
      <input
        type="date"
        value={dateRange.end}
        onChange={e => setDateRange(prev => ({ ...prev, end: e.target.value }))}
      />

      {/* 表格渲染 */}
      <table>
        <thead>
          {table.getHeaderGroups().map(headerGroup => (
            <tr key={headerGroup.id}>
              {headerGroup.headers.map(header => (
                <th key={header.id}>{header.renderHeader()}</th>
              ))}
            </tr>
          ))}
        </thead>
        <tbody>
          {table.getRowModel().rows.map(row => (
            <tr key={row.id}>
              {row.getVisibleCells().map(cell => (
                <td key={cell.id}>{cell.renderCell()}</td>
              ))}
            </tr>
          ))}
        </tbody>
      </table>
    </div>
  );
}

二、字符串格式日期的过滤处理

API返回的YYYY-MM-DD格式字符串有个天然优势:字典序和日期时间顺序完全一致,所以有两种过滤思路:

1. 直接字符串对比(推荐)

不用转换为Date对象,直接对比字符串,性能更高还能避免时区问题:

const filterDateRange = (rowDate: string, start: string, end: string) => {
  if (!start && !end) return true;
  if (start && rowDate < start) return false;
  if (end && rowDate > end) return false;
  return true;
};

注意:确保输入框的日期格式和API返回一致(原生type="date"的value就是YYYY-MM-DD,刚好匹配)。

2. 转换为Date对象对比

如果日期格式不统一(比如存在MM/DD/YYYY),或者需要处理时间部分,就转成Date对象:

const filterDateRange = (rowDate: string, start: string, end: string) => {
  const rowDateTime = new Date(rowDate);
  const startDateTime = start ? new Date(start) : new Date(-8640000000000000); // 极小时间值
  const endDateTime = end ? new Date(end) : new Date(8640000000000000); // 极大时间值

  // 处理无效日期(比如字符串格式错误)
  if (isNaN(rowDateTime.getTime())) return false;

  return rowDateTime >= startDateTime && rowDateTime <= endDateTime;
};

三、日期范围过滤的最佳方案

  1. 优先用字符串直接对比:对于YYYY-MM-DD、YYYY-MM-DD HH:mm:ss这类标准格式,字符串对比性能更好,无时区问题。
  2. 封装可复用过滤函数:把日期过滤逻辑抽成独立函数,方便在多个组件中复用,避免重复代码。
  3. 结合表格库原生过滤机制:比如给日期列单独配置filterFn,比全局过滤更清晰,维护起来更方便。
  4. 处理边界情况:
    • 当开始日期大于结束日期时,自动交换两者;
    • 输入为空时,不对该边界做限制;
    • 校验日期格式,过滤无效日期的行。

内容的提问来源于stack exchange,提问作者Bishal Khatri

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 22:31:30