跟着官方示例学习 @tanStack-table --- Column Filters

🌲系列一:跟着官方示例学习 @tanStack-table --- Basic

🌲系列二:跟着官方示例学习 @tanStack-table --- Header Groups


👏 Sort

上次我们已经成功把表格渲染出来了,还用了 column group 做了结构分组。今天我们要给它加上「排序」的能力。

点击一下表头,就可以按升序、再点一下就降序、再点回到默认排序。是不是很熟悉?

🚦 第一步:启用排序功能

我们只需要在创建 table 的时候把它添加进去即可:

tsx 复制代码
const table = useReactTable({
  data,
  columns,
  getCoreRowModel: getCoreRowModel(),
  getSortedRowModel: getSortedRowModel(), // 👈 开启排序
});

🔎 getSortedRowModel 是一个内置的排序逻辑,它会根据你点击的列自动处理排序逻辑。

🧲 第二步:让表头"可以点击"

在渲染表头的时候,我们只需要加上一点交互行为,@tanstack/react-table 已经为我们准备好了相关的 API:

tsx 复制代码
<div
  className={header.column.getCanSort() ? 'cursor-pointer select-none' : ''}
  onClick={header.column.getToggleSortingHandler()}
>
  {flexRender(header.column.columnDef.header, header.getContext())}
  {{
    asc: ' 🔼',
    desc: ' 🔽',
  }[header.column.getIsSorted() as string] ?? null}
</div>

📌 分析一下这段代码在干什么:

getCanSort():判断当前列是否允许排序

getToggleSortingHandler():返回一个可以用于切换该列排序状态的函数

getIsSorted():告诉你当前列是否被排序了,是什么方向(升/降)

🔼 / 🔽 是我们手动加的图标,用来提示用户当前排序状态

🔔 对官方示例代码可能存在一些删减的情况

代码地址🔗:Gitee

官方代码地址🔗: @tanStack/react-table

🤝 Filter

可以理解为 Excel 中的"筛选器",根据你输入的关键词、选择的状态,甚至输入的数值范围来过滤你想看的行数据。

🛠 核心状态:columnFilters + getFilteredRowModel

过滤功能的核心只有两个部分:

1️⃣ 声明过滤状态

tsx 复制代码
const [columnFilters, setColumnFilters] = React.useState<ColumnFiltersState>([]);

这是一个数组,记录了每一列当前的过滤条件。

2️⃣ useReactTable 过滤逻辑

tsx 复制代码
const table = useReactTable({
  //...
  state: {
    columnFilters,
  },
  onColumnFiltersChange: setColumnFilters,
  getFilteredRowModel: getFilteredRowModel(), // 👈 启用内置过滤逻辑
});

只要你在列上调用了 setFilterValue(),就会更新 columnFilters 状态,并自动触发过滤逻辑。

🧩 渲染每列的过滤输入框

我们在表头中为每一列添加了一个 <Filter /> 组件,渲染不同类型的过滤器:

tsx 复制代码
{header.column.getCanFilter() ? (
  <div>
    <Filter column={header.column} />
  </div>
) : null}

通过 getCanFilter() API 🔗 判断是否启用过滤器,避免一些不可过滤的列出错。

🔀 三种不同的过滤器组件

我们根据列定义中 meta.filterVariant 的配置,渲染不同样式的过滤器输入框:

✅ 1. 文本过滤(默认)

tsx 复制代码
<DebouncedInput
  className="w-36 border shadow rounded"
  onChange={(value) => column.setFilterValue(value)}
  placeholder="Search..."
  type="text"
  value={(columnFilterValue ?? '') as string}
/>

适用于 firstName、lastName 等文本字段。

🧮 2. 范围过滤(range)

tsx 复制代码
<div className="flex space-x-2">
  <DebouncedInput
    type="number"
    value={(columnFilterValue as [number, number])?.[0] ?? ''}
    onChange={(value) =>
      column.setFilterValue((old: [number, number]) => [value, old?.[1]])
    }
    placeholder={`Min`}
    className="w-24 border shadow rounded"
  />
  <DebouncedInput
    type="number"
    value={(columnFilterValue as [number, number])?.[1] ?? ''}
    onChange={(value) =>
      column.setFilterValue((old: [number, number]) => [old?.[0], value])
    }
    placeholder={`Max`}
    className="w-24 border shadow rounded"
  />
</div>

适用于 age、visits、progress 这种数值型列。

🧾 3. 下拉过滤(select)

tsx 复制代码
<select
  onChange={(e) => column.setFilterValue(e.target.value)}
  value={columnFilterValue?.toString()}
>
  <option value="">All</option>
  <option value="complicated">complicated</option>
  <option value="relationship">relationship</option>
  <option value="single">single</option>
</select>

适用于枚举类型的字段,例如 status,用户可以直接选择"Single"、"Complicated" 等值进行筛选。

🔔 对官方示例代码可能存在一些删减的情况

代码地址🔗:Gitee

官方代码地址🔗: @tanStack/react-table

🔍 getFacetedRowModel 智能列过滤器

🥒 Column Faceting APIs

markdown 复制代码
getFacetedRowModel
        ↓
getFacetedUniqueValues ← 用来生成下拉框 / datalist
getFacetedMinMaxValues ← 用来生成范围筛选器

✅ getFacetedUniqueValues 这个方法的作用是:

根据当前列的所有数据(在其它列过滤器生效的前提下)提取唯一值集合。

它通常用于构建下拉选择(select)或自动补全(datalist) 的过滤器。例如,性别列只会返回 ['Male', 'Female'],品牌列可能是 ['Nike', 'Adidas', 'Puma']。

⚠️ 注意:这个方法只会基于当前"可见数据"返回唯一值,意味着当用户先选了其他筛选条件时,这里的值也会动态变化,确保是"上下文相关"的。

✅ getFacetedMinMaxValues 这个方法的作用是:

返回当前列中的最小值和最大值,用于构建范围筛选器(如价格区间、年龄段等)。

比如在一个年龄列中,当前剩下的可选数据可能年龄范围是 [22, 45],这个 API 就会返回这个区间值,让你可以渲染一个最小值/最大值输入框,限制在合理范围内。

🔔 对官方示例代码可能存在一些删减的情况

代码地址🔗:Gitee

官方代码地址🔗: @tanStack/react-table

🔎 Fuzzy Filtering 模糊匹配过滤器

在表格搜索时,用户希望在搜索时不需要完全输入准确的值,也能快速定位目标数据。这时候,"模糊匹配过滤器"就派上用场了。

TanStack Table 支持自定义过滤器函数,我们可以结合 @tanstack/match-sorter-utils 提供的 rankItem 工具,轻松实现模糊匹配。

✨ 什么是模糊匹配(Fuzzy Matching)? 模糊匹配是一种容错搜索机制,它不要求用户输入的关键词与表格数据完全一致。

  • ✅ 容忍拼写错误

  • ✅ 忽略大小写

  • ✅ 关键词顺序灵活

🧠 实现方式:自定义 fuzzyFilter 函数

tsx 复制代码
import { rankItem } from '@tanstack/match-sorter-utils'
import { FilterFn } from '@tanstack/react-table'

// 自定义模糊匹配过滤函数
const fuzzyFilter: FilterFn<any> = (row, columnId, value, addMeta) => {
  const itemRank = rankItem(row.getValue(columnId), value)
  addMeta({ itemRank }) // 可选:供排序使用
  return itemRank.passed
}

🔌 使用方式 在 useReactTable 中将它挂载到 filterFns 上:

tsx 复制代码
const table = useReactTable({
  data,
  columns,
  filterFns: {
    fuzzy: fuzzyFilter,
  },
  globalFilterFn: 'fuzzy', // 全局搜索启用模糊匹配
  ...
})

在列中启用模糊过滤:

tsx 复制代码
{
  accessorKey: 'fullName',
  header: 'Full Name',
  filterFn: 'fuzzy', // 列级别启用 fuzzy
}

💡 模糊匹配 + 排序联动 模糊搜索通常会用 rankItem.score 来排序最相关的结果,你还可以监听过滤状态,自动对当前列排序:

tsx 复制代码
React.useEffect(() => {
  if (table.getState().columnFilters[0]?.id === 'fullName') {
    if (table.getState().sorting[0]?.id !== 'fullName') {
      table.setSorting([{ id: 'fullName', desc: false }])
    }
  }
}, [table.getState().columnFilters[0]?.id])

TanStack Table 内置了一些 filter function API🔗

tsx 复制代码
{
  accessorKey: 'id',
  filterFn: 'equalsString', // note: normal non-fuzzy filter column - exact match required
},
{
  accessorKey: 'firstName',
  filterFn: 'includesStringSensitive', // note: normal non-fuzzy filter column - case sensitive
},
{
  accessorKey: 'lastName',
  filterFn: 'includesString', // note: normal non-fuzzy filter column - case insensitive
},

🔔 对官方示例代码可能存在一些删减的情况

代码地址🔗:Gitee

官方代码地址🔗: @tanStack/react-table

相关推荐
Dontla2 小时前
为什么React列表项需要key?(React key)(稳定的唯一标识key有助于React虚拟DOM优化重绘大型列表)
javascript·react.js·ecmascript
EndingCoder3 小时前
React从基础入门到高级实战:React 实战项目 - 项目三:实时聊天应用
前端·react.js·架构·前端框架
阿阳微客4 小时前
Steam 搬砖项目深度拆解:从抵触到真香的转型之路
前端·笔记·学习·游戏
德育处主任Pro4 小时前
『React』Fragment的用法及简写形式
前端·javascript·react.js
CodeBlossom5 小时前
javaweb -html -CSS
前端·javascript·html
打小就很皮...5 小时前
HBuilder 发行Android(apk包)全流程指南
前端·javascript·微信小程序
集成显卡6 小时前
PlayWright | 初识微软出品的 WEB 应用自动化测试框架
前端·chrome·测试工具·microsoft·自动化·edge浏览器
前端小趴菜057 小时前
React - 组件通信
前端·react.js·前端框架
Amy_cx7 小时前
在表单输入框按回车页面刷新的问题
前端·elementui
dancing9998 小时前
cocos3.X的oops框架oops-plugin-excel-to-json改进兼容多表单导出功能
前端·javascript·typescript·游戏程序