Capítulo 37 de 54

Chapter 37: Fuzzy Filtering (React) Guide

Core Idea

Fuzzy (approximate) filtering isn't a built-in feature — it's a recipe combining a custom filterFn built on @tanstack/match-sorter-utils' rankItem, filterMeta to carry the rank score, and a paired custom sortFn that reads that score, so results filter and sort by match quality.

Key Concepts

  • Dependency: @tanstack/match-sorter-utils, TanStack's fork of Kent C. Dodds' match-sorter, adapted for row-by-row filtering. Optional in principle — you could write ranking logic yourself — but this is the standard path.
  • The filter function calls rankItem(row.getValue(columnId), value), stores the resulting RankingInfo via addMeta?.({ itemRank }) (optional-chained since addMeta may be undefined), and returns itemRank.passed.
  • Typing the stored rank requires the filterMeta slot (see Table and Column Meta Guide): declare interface FuzzyFilterMeta { itemRank?: RankingInfo }, build a FuzzyFeatures = TableFeatures & { filterMeta: FuzzyFilterMeta } type, annotate the filter function as FilterFn<FuzzyFeatures, RowData>, and register filterMeta: metaHelper<FuzzyFilterMeta>() alongside filterFns: { fuzzy: fuzzyFilter } in tableFeatures(). No global declare module augmentation needed — the slot is scoped to that one features object.
  • The paired sort function reads rowA.columnFiltersMeta[columnId] (the meta stashed by the filter) and calls compareItems(rankA, rankB) from match-sorter-utils, falling back to sortFn_alphanumeric when ranks tie or no ranking info exists (e.g. sorting without an active filter). Register it as sortFns: { fuzzy: fuzzySort }.
  • Two application modes, both using the same registered fuzzy name: as globalFilterFn: 'fuzzy' on the table for cross-column search, or as a per-column filterFn: 'fuzzy' (commonly paired with sortFn: 'fuzzy' on the same column) for one field — e.g. a computed fullName accessor column. Either can also skip registration and pass the function directly instead of a string.
  • Needs rowSortingFeature + sortedRowModel: createSortedRowModel() registered alongside filtering if you also want the sort-by-rank behavior.

Code Examples

interface FuzzyFilterMeta { itemRank?: RankingInfo }
type FuzzyFeatures = TableFeatures & { filterMeta: FuzzyFilterMeta }

const fuzzyFilter: FilterFn<FuzzyFeatures, RowData> = (row, columnId, value, addMeta) => {
  const itemRank = rankItem(row.getValue(columnId), value)
  addMeta?.({ itemRank })
  return itemRank.passed
}

const fuzzySort: SortFn<FuzzyFeatures, Person> = (rowA, rowB, columnId) => {
  const a = rowA.columnFiltersMeta[columnId]
  const dir = a ? compareItems(a.itemRank!, rowB.columnFiltersMeta[columnId]?.itemRank!) : 0
  return dir === 0 ? sortFn_alphanumeric(rowA, rowB, columnId) : dir
}

const features = tableFeatures({
  columnFilteringFeature, globalFilteringFeature, rowSortingFeature,
  filteredRowModel: createFilteredRowModel(), sortedRowModel: createSortedRowModel(),
  filterFns: { fuzzy: fuzzyFilter }, sortFns: { fuzzy: fuzzySort },
  filterMeta: metaHelper<FuzzyFilterMeta>(),
})
const table = useTable({ features, columns, data, globalFilterFn: 'fuzzy' })
  • What it demonstrates: the complete filter→meta→sort chain — the filter ranks and stashes, the sort reads the stash, both registered under the same 'fuzzy' name.

Key Takeaways

  1. Fuzzy filtering is a pattern built from three existing primitives (custom filterFn, filterMeta, paired sortFn), not a separate feature to register.
  2. Always provide the alphanumeric fallback in the sort function — without it, rows with equal or missing rank data have no defined order.
  3. Use as globalFilterFn for whole-table search, or per-column filterFn/sortFn for one field (e.g. a combined name column) — same registered function either way.

Connects To

  • Table and Column Meta Guide: filterMeta/metaHelper, the mechanism carrying rank data from filter to sort.
  • Global Filtering (React) Guide / Column Filtering (React) Guide: where globalFilterFn/filterFn get set.
  • Sorting (React) Guide: sortFn_alphanumeric and the general custom-sort-function shape.