框架
版本
企业版

全局过滤指南

示例

想直接看实现?可以参考以下示例

API

全局过滤 API

全局过滤指南

过滤有两种方式:列过滤和全局过滤。

本指南将重点介绍全局过滤,即应用于所有列的过滤器。

客户端过滤 vs 服务器端过滤

如果您有大型数据集,您可能不想将所有数据加载到客户端浏览器中进行过滤。在这种情况下,您很可能需要实现服务器端过滤、排序、分页等。

但是,正如在《分页指南》中所讨论的,许多开发人员低估了客户端在不影响性能的情况下可以加载的行数。TanStack Table 的示例通常经过测试,可以处理多达 100,000 行甚至更多行,并提供不错的客户端过滤、排序、分页和分组性能。这并不一定意味着您的应用程序可以处理这么多行,但如果您的表最多只有几千行,您也许可以利用 TanStack Table 提供的客户端过滤、排序、分页和分组功能。

TanStack Table 可以高效处理数千行客户端数据。不要在没有仔细考虑的情况下就排除客户端过滤、分页、排序等选项。

每种用例都不同,具体取决于表的复杂性、有多少列、每块数据的大小等。需要注意的主要瓶颈是

  1. 您的服务器能否在合理的时间内(和成本)查询所有数据?
  2. 获取的总数据量是多少?(如果没有太多列,这可能不会像您想的那么糟糕。)
  3. 如果一次性加载所有数据,客户端浏览器是否会占用过多内存?

如果您不确定,可以始终从客户端过滤和分页开始,然后随着数据量的增长,将来切换到服务器端策略。

手动服务器端全局过滤

如果您已决定需要实现服务器端全局过滤而不是使用内置的客户端全局过滤,那么方法如下。

对于手动服务器端全局过滤,不需要 getFilteredRowModel 表选项。相反,您传递给表的 data 应该已经过过滤。但是,如果您传递了 getFilteredRowModel 表选项,则可以通过将 manualFiltering 选项设置为 true 来告诉表跳过它。

jsx
const table = useReactTable({
  data,
  columns,
  // getFilteredRowModel: getFilteredRowModel(), // not needed for manual server-side global filtering
  manualFiltering: true,
})
const table = useReactTable({
  data,
  columns,
  // getFilteredRowModel: getFilteredRowModel(), // not needed for manual server-side global filtering
  manualFiltering: true,
})

注意:在使用手动全局过滤时,本指南其余部分讨论的许多选项将无效。当 manualFiltering 设置为 true 时,表实例不会对传递给它的行应用任何全局过滤逻辑。相反,它会假定行已过滤,并将按原样使用您传递给它的数据。

客户端全局过滤

如果您正在使用内置的客户端全局过滤,首先您需要将 getFilteredRowModel 函数传递给表选项。

jsx
import { useReactTable, getFilteredRowModel } from '@tanstack/react-table'
//...
const table = useReactTable({
  // other options...
  getCoreRowModel: getCoreRowModel(),
  getFilteredRowModel: getFilteredRowModel(), // needed for client-side global filtering
})
import { useReactTable, getFilteredRowModel } from '@tanstack/react-table'
//...
const table = useReactTable({
  // other options...
  getCoreRowModel: getCoreRowModel(),
  getFilteredRowModel: getFilteredRowModel(), // needed for client-side global filtering
})

全局过滤函数

globalFilterFn 选项允许您指定将用于全局过滤的过滤函数。过滤函数可以是一个引用内置过滤函数的字符串,一个引用通过 tableOptions.filterFns 选项提供的自定义过滤函数的字符串,或者一个自定义过滤函数。

jsx
const table = useReactTable({
  data,
  columns,
  getCoreRowModel: getCoreRowModel(),
  getFilteredRowModel: getFilteredRowModel(),
  globalFilterFn: 'text' // built-in filter function
})
const table = useReactTable({
  data,
  columns,
  getCoreRowModel: getCoreRowModel(),
  getFilteredRowModel: getFilteredRowModel(),
  globalFilterFn: 'text' // built-in filter function
})

默认情况下,有 10 个内置过滤函数可供选择

  • includesString - 忽略大小写的字符串包含
  • includesStringSensitive - 区分大小写的字符串包含
  • equalsString - 忽略大小写的字符串相等
  • equalsStringSensitive - 区分大小写的字符串相等
  • arrIncludes - 数组中的项包含
  • arrIncludesAll - 数组中包含所有项
  • arrIncludesSome - 数组中包含部分项
  • equals - 对象/引用相等 Object.is/===
  • weakEquals - 弱对象/引用相等 ==
  • inNumberRange - 数字范围包含

您也可以定义自己的自定义过滤函数,作为 globalFilterFn 表选项。

全局过滤状态

全局过滤状态存储在表的内部状态中,可以通过 table.getState().globalFilter 属性访问。如果您想在表之外持久化全局过滤状态,可以使用 onGlobalFilterChange 选项提供一个回调函数,该函数将在全局过滤状态更改时调用。

jsx
const [globalFilter, setGlobalFilter] = useState<any>([])

const table = useReactTable({
  // other options...
  state: {
    globalFilter,
  },
  onGlobalFilterChange: setGlobalFilter
})
const [globalFilter, setGlobalFilter] = useState<any>([])

const table = useReactTable({
  // other options...
  state: {
    globalFilter,
  },
  onGlobalFilterChange: setGlobalFilter
})

全局过滤状态定义为一个具有以下形状的对象

jsx
interface GlobalFilter {
  globalFilter: any
}
interface GlobalFilter {
  globalFilter: any
}

在 UI 中添加全局过滤输入

TanStack table 不会自动为您的表添加全局过滤输入 UI。您应该手动将其添加到 UI 中,以便用户可以过滤表。例如,您可以在表上方添加一个输入 UI,让用户输入搜索词。

jsx
return (
  <div>
    <input
      value=""
      onChange={e => table.setGlobalFilter(String(e.target.value))}
      placeholder="Search..."
    />
  </div>
)
return (
  <div>
    <input
      value=""
      onChange={e => table.setGlobalFilter(String(e.target.value))}
      placeholder="Search..."
    />
  </div>
)

自定义全局过滤函数

如果您想使用自定义全局过滤函数,您可以定义该函数并将其传递给 globalFilterFn 选项。

注意:使用模糊过滤函数进行全局过滤是一个常见的想法。这将在《模糊过滤指南》中讨论。

jsx
const customFilterFn = (rows, columnId, filterValue) => {
  // custom filter logic
}

const table = useReactTable({
  // other options...
  globalFilterFn: customFilterFn
})
const customFilterFn = (rows, columnId, filterValue) => {
  // custom filter logic
}

const table = useReactTable({
  // other options...
  globalFilterFn: customFilterFn
})

初始全局过滤状态

如果您想在表初始化时设置初始全局过滤状态,可以将全局过滤状态作为 table initialState 选项的一部分传递。

但是,您也可以仅在 state.globalFilter 选项中指定初始全局过滤状态。

jsx
const [globalFilter, setGlobalFilter] = useState("search term") //recommended to initialize globalFilter state here

const table = useReactTable({
  // other options...
  initialState: {
    globalFilter: 'search term', // if not managing globalFilter state, set initial state here
  }
  state: {
    globalFilter, // pass our managed globalFilter state to the table
  }
})
const [globalFilter, setGlobalFilter] = useState("search term") //recommended to initialize globalFilter state here

const table = useReactTable({
  // other options...
  initialState: {
    globalFilter: 'search term', // if not managing globalFilter state, set initial state here
  }
  state: {
    globalFilter, // pass our managed globalFilter state to the table
  }
})

注意:不要同时使用 initialState.globalFilter 和 state.globalFilter,因为 state.globalFilter 中的已初始化状态将覆盖 initialState.globalFilter。

禁用全局过滤

默认情况下,全局过滤对所有列都启用。您可以使用 enableGlobalFilter 表选项禁用所有列的全局过滤。您还可以通过将 enableFilters 表选项设置为 false 来关闭列过滤和全局过滤。

禁用全局过滤将导致 column.getCanGlobalFilter API 对该列返回 false。

jsx
const columns = [
  {
    header: () => 'Id',
    accessorKey: 'id',
    enableGlobalFilter: false, // disable global filtering for this column
  },
  //...
]
//...
const table = useReactTable({
  // other options...
  columns,
  enableGlobalFilter: false, // disable global filtering for all columns
})
const columns = [
  {
    header: () => 'Id',
    accessorKey: 'id',
    enableGlobalFilter: false, // disable global filtering for this column
  },
  //...
]
//...
const table = useReactTable({
  // other options...
  columns,
  enableGlobalFilter: false, // disable global filtering for all columns
})
我们的合作伙伴
Code Rabbit
AG Grid
订阅 Bytes

您的每周 JavaScript 资讯。每周一免费发送给超过 10 万开发者。

Bytes

无垃圾邮件。您可以随时取消订阅。

订阅 Bytes

您的每周 JavaScript 资讯。每周一免费发送给超过 10 万开发者。

Bytes

无垃圾邮件。您可以随时取消订阅。