Capítulo 40 de 54

Chapter 40: Grouping (React) Guide

Core Idea

columnGroupingFeature categorizes rows by shared column values into a tree (grouped rows hold matching rows as subRows, replacing them at the position of the first match) — it's independent of rowAggregationFeature now, so register grouping alone for pure categorization, or both together when grouped rows should also show computed totals.

Key Concepts

  • Column order interaction: grouping is the third stage of the order pipeline (pinning → manual columnOrder → grouping). With an active grouping state and groupedColumnMode: 'reorder' (default-equivalent behavior — grouped columns move to the front) or 'remove' (grouped columns disappear from the flow entirely), or false (leave column position untouched).
  • Setup: columnGroupingFeature + groupedRowModel: createGroupedRowModel() for client-side; manualGrouping: true (skip the row model) for server-side — though the docs note there isn't yet an easy, well-established pattern for server-side grouping; expect custom cell-rendering work.
  • Grouping state: GroupingState = string[] — an ordered list of column ids, e.g. ['region', 'plan'] groups by region first, then by plan within each region. table.setGrouping([...]), table.resetGrouping().
  • Pair with expanding to let users collapse/expand groups: register rowExpandingFeature + expandedRowModel: createExpandedRowModel() alongside grouping.
  • Auto-reset caveat: the client-side grouped row model triggers the page-index and expanded-state auto-reset hooks when grouping inputs change (governed by autoResetPageIndex/autoResetExpanded/autoResetAll). Under manual (server-side) grouping with the row model skipped, those hooks don't fire — reset dependent state by hand in the grouping change handler.
  • Ownership: external atom via atoms: { grouping: atom } (v9-recommended) or classic state.grouping + onGroupingChange.
  • Column-level APIs: column.toggleGrouping(), column.getToggleGroupingHandler(), column.getCanGroup(), column.getIsGrouped(), column.getGroupedIndex() (position within the grouping order).
  • Row-level helpers: row.getIsGrouped(), row.getGroupingValue(columnId), row.groupingColumnId, row.groupingValue.
  • Cell-level helpers: cell.getIsGrouped(), cell.getIsPlaceholder() (a cell in a grouped row for a column not being grouped by — typically rendered blank).
  • Row-model access: table.getGroupedRowModel() / table.getPreGroupedRowModel() (the row set before grouping — this is what the Row Models Guide's fixed pipeline order refers to).

Code Examples

const features = tableFeatures({
  columnGroupingFeature, rowExpandingFeature,
  groupedRowModel: createGroupedRowModel(),
  expandedRowModel: createExpandedRowModel(),
})
const table = useTable({ features, columns, data, groupedColumnMode: 'reorder' })

table.setGrouping(['region', 'plan'])

// rendering a grouped cell vs. a placeholder cell vs. an ordinary cell
cell.getIsGrouped() ? renderGroupHeaderCell(cell)
  : cell.getIsPlaceholder() ? null
  : renderNormalCell(cell)
  • What it demonstrates: the three-way branch every grouped table's cell renderer needs — grouped, placeholder, or ordinary.

Key Takeaways

  1. Grouping alone gives you categorized rows with no totals — pair it with rowAggregationFeature (previous chapter) when groups need aggregate values.
  2. Under manual grouping, reset pagination/expansion by hand — the auto-reset hooks that fire for client-side grouping don't fire when the row model is skipped.
  3. groupedColumnMode decides whether grouped columns physically move to the front, disappear, or stay put — pick deliberately, it changes what columnOrder ends up meaning.

Connects To

  • Aggregation (React) Guide: adding computed totals to grouped rows.
  • Expanding (React) Guide: collapsing/expanding the group tree grouping produces.
  • Column Ordering (React) Guide: the full three-stage order pipeline grouping participates in.