Capítulo 13 de 54

Chapter 13: Row Models Guide

Core Idea

Row models are the pipeline that turns raw data into what actually renders — filtered, grouped, sorted, expanded, and paginated in that fixed order — and table.getRowModel() is almost always the one you render from, since it composes whichever stages are enabled.

Key Concepts

  • Row model factories are registered as slots inside tableFeatures(), alongside the feature that needs them. The core row model (1:1 with data) is automatic; everything else is opt-in.
  • Slot → factory → purpose: filteredRowModelcreateFilteredRowModel() (column + global filtering); sortedRowModelcreateSortedRowModel(); paginatedRowModelcreatePaginatedRowModel(); expandedRowModelcreateExpandedRowModel(); groupedRowModelcreateGroupedRowModel() (grouping, and aggregation when rowAggregationFeature is also registered); facetedRowModel/facetedMinMaxValues/facetedUniqueValues ← their matching create* factories, for faceted-filter UIs.
  • Function registries are separate slots: filterFns, sortFns, aggregationFns on tableFeatures() are named-function maps. Register only what you use under a conventional key (filterFns: { includesString: filterFn_includesString }) to keep the string-typed filterFn/sortFn/aggregationFn column options type-safe and tree-shaken. Spreading the full built-in registry works but is discouraged — it pulls in every built-in implementation. Passing a function directly to a column's filterFn/sortFn/aggregationFn needs no registration at all.
  • Fixed execution order: getCoreRowModelgetFilteredRowModelgetGroupedRowModelgetSortedRowModelgetExpandedRowModelgetPaginatedRowModelgetRowModel. Filter, then group, then sort, then expand, then paginate — always in that order when the corresponding feature/row-model is enabled. A disabled feature or a manual* flag makes that stage fall back to its getPre*RowModel (pass-through).
  • getPre*RowModel variants exist for every stage (getPreFilteredRowModel, getPreGroupedRowModel, getPreSortedRowModel, getPreExpandedRowModel, getPrePaginatedRowModel) — the row set before that stage runs, useful for computing something (like grand totals) against the un-transformed set.
  • Selection-aware row models: getSelectedRowModel (selected rows, after core), getPreSelectedRowModel (= core), getGroupedSelectedRowModel (selected rows after grouping+sorting), getFilteredSelectedRowModel (selected rows after filtering).
  • Every row model exposes rows 3 ways: .rows (array), .flatRows (sub-rows flattened to top level), .rowsById (O(1) lookup by row id) — reach for rowsById whenever you need "find this specific row" instead of scanning .rows.

Code Examples

const features = tableFeatures({
  columnFilteringFeature, rowSortingFeature, rowPaginationFeature,
  filteredRowModel: createFilteredRowModel(),
  sortedRowModel: createSortedRowModel(),
  paginatedRowModel: createPaginatedRowModel(),
  filterFns: { includesString: filterFn_includesString },
  sortFns: { alphanumeric: sortFn_alphanumeric },
})

// render loop uses the composed result:
table.getRowModel().rows            // final rows: filtered → sorted → paginated
table.getRowModel().rowsById['42']  // O(1) lookup
  • What it demonstrates: registering a feature (state/APIs) is paired 1:1 with registering its row-model factory (client-side processing) — this is the same feature/row-model split from the Features Guide, applied concretely to filtering/sorting/pagination.

Key Takeaways

  1. Render from table.getRowModel(), not a specific stage's getter — it already knows which stages are actually enabled.
  2. The pipeline order (filter → group → sort → expand → paginate) is fixed and matters for reasoning about bugs: e.g. sort options never affect which rows are grouped, only their order within/after grouping.
  3. Register function names individually (filterFns: { includesString: ... }) rather than spreading full built-in registries — this is a real bundle-size lever, not just style.
  4. rowsById beats .find() over .rows whenever you already know the row id.

Connects To

  • Features Guide: the feature/row-model/function-registry split this guide implements concretely.
  • Row Model Factories (API reference): full signatures for every create*RowModel().
  • Client-Side vs Server-Side Guide: what changes when a stage's row model is omitted in favor of manual*.
  • Worker Row Models Guide (Experimental): offloading the expensive stages of this same pipeline to a Web Worker.