PrimeUI PRO for React is now available 🚀View Demos

useTreeTable

Hierarchical data table built on useDataTable with treeMode enabled, sort, filter, paginate, select, expand, and edit tree-shaped data.

NameSizeType
basic-demo

Usage#

TreeTable is not a separate hook, it is useDataTable with treeMode: true. The hook flattens the visible part of the tree (respecting expandedKeys), so every other feature (sort, filter, pagination, selection, editing, reorder, export) works the same way as on flat data.

import { useDataTable } from '@primereact/headless/datatable';
const tree = useDataTable({
    data: nodes,
    dataKey: 'key',
    treeMode: true,
    expandedKeys,
    onExpandedChange: (e) => setExpandedKeys(e.value)
});

Nodes are objects of the shape { key, data, children? }. Flat rows produced by the hook are stamped with helpers used by the renderer:

FieldTypeMeaning
_treeLevelnumberZero-based depth in the tree (used for indentation and aria-level).
_treeHasChildrenbooleanWhether the row has children (drives the expander vs. spacer).
_treePosInSetnumberOne-based position among siblings (aria-posinset).
_treeSetSizenumberTotal siblings at this depth (aria-setsize).

Features#

All useDataTable features work the same way; the table role becomes treegrid and rows pick up tree-aware ARIA attributes. A few things behave differently in tree mode:

  • Filter, column filters and the global filter keep ancestor nodes when any descendant matches, so the result stays connected to its roots
  • Selection, checkbox selection cascades to descendants; partially-selected parents are reported through selection.isPartiallySelected(key)
  • Pagination, the paginator slices root-level nodes only; expanded children stay inside the same page

Working with callbacks#

Controlled expansion#

const [expandedKeys, setExpandedKeys] = React.useState<Record<string, boolean>>({ '0': true });
 
const tree = useDataTable({
    data: nodes,
    dataKey: 'key',
    treeMode: true,
    expandedKeys,
    onExpandedChange: (e) => setExpandedKeys(e.value)
});

Filter + sort + pagination#

Pass the same filters / sortField / paginator props as on a flat DataTable; the hook re-runs them against the tree.

const tree = useDataTable({
    data: nodes,
    treeMode: true,
    paginator: true,
    rows: 10,
    filters,
    onFilter: (e) => setFilters(e.filters),
    sortField,
    sortOrder,
    onSortChange: (e) => {
        setSortField(e.field);
        setSortOrder(e.order);
    }
});

API#

useDataTable#

NameTypeDefault

useDataTableRow#

Accessibility#

role="treegrid" is applied to the table; rows expose aria-level, aria-expanded, aria-posinset, aria-setsize. Expander buttons emit aria-expanded and a descriptive aria-label. See Primitive for full WAI-ARIA compliance details.