Introducing PrimeReact v11-alpha 🎉Discover Now

useTree

Hooks that manage tree state, keyboard navigation, selection, and drag-drop.

  • Documents
basic-demo

Usage#

import { useTree, useTreeNode } from '@primereact/headless/tree';
 
const tree = useTree({ value: nodes, selectionMode: 'single' });
const { rootProps } = tree;
 
const treeNode = useTreeNode({ node: nodes[0], context: tree, index: 0 });
const { state, nodeProps, contentProps } = treeNode;
const toggleProps = tree.getToggleProps(nodes[0]);
 
return (
    <div {...rootProps}>
        <ul {...tree.getListProps(false)}>
            <li {...nodeProps}>
                <div {...contentProps}>
                    <button {...toggleProps}></button>
                </div>
            </li>
        </ul>
    </div>
);

useTree manages root state while useTreeNode consumes that context to return prop objects for each node element — see Primitive for a component-based API.

Features#

  • Two-hook architecture: useTree for root state, useTreeNode for per-node behavior
  • Returns spread-ready prop objects via rootProps, getNodeProps, getToggleProps, getListProps, filterProps
  • Three selection modes: single, multiple, checkbox with parent-child propagation
  • Controlled and uncontrolled expansion and selection state
  • Built-in drag-drop with scope validation for same-tree and cross-tree transfers
  • Typeahead search across visible nodes

Behavior#

Default Expanded Keys#

Use defaultExpandedKeys to set initially expanded nodes. Keys are a Record<string, boolean>.

const tree = useTree({ value: nodes, defaultExpandedKeys: { '0': true, '1': true } });

Controlled Expansion#

Use expandedKeys and onExpandedChange for full programmatic control.

const [expandedKeys, setExpandedKeys] = React.useState<TreeExpandedKeys>({ '0': true });
const tree = useTree({
    value: nodes,
    expandedKeys,
    onExpandedChange: (e) => setExpandedKeys(e.value)
});

Selection Mode#

Set selectionMode to single, multiple, or checkbox. Use selectionKeys and onSelectionChange for controlled selection.

const tree = useTree({ value: nodes, selectionMode: 'single' });

In checkbox mode, selection keys use { checked: boolean, partialChecked: boolean } shape. Parent-child propagation is handled automatically.

Meta Key Selection#

In multiple mode, metaKeySelection controls whether the meta key (Cmd/Ctrl) is required to add to existing selections. Defaults to true.

const tree = useTree({ value: nodes, selectionMode: 'multiple', metaKeySelection: false });

Drag and Drop#

Enable drag-drop by setting draggableNodes and droppableNodes. Use draggableScope and droppableScope to restrict transfers between trees.

const tree = useTree({
    value: nodes,
    draggableNodes: true,
    droppableNodes: true,
    onValueChange: (e) => setNodes(e.value)
});

Filtering#

Spread filterProps on an input element to enable search filtering. The hook provides autoComplete: 'off' and keyboard handling.

<input {...tree.filterProps} />

Conditional Rendering with state.expanded#

Use state.expanded from useTreeNode to conditionally render child nodes.

const { state } = useTreeNode({ node, context: tree, index: 0 });
 
{
    state.expanded && node.children && (
        <ul {...tree.getListProps(true)}>
            {node.children.map((child, i) => (
                <TreeNodeItem key={child.key} node={child} index={i} />
            ))}
        </ul>
    );
}

Custom Styling with Data Attributes#

Every prop object includes data-scope="tree" and a data-part attribute. State-dependent attributes are added automatically to enable CSS-only styling.

rootProps#

AttributeDescription
data-scope"tree"
data-part"root"
data-drag-hoverPresent when a node is being dragged over root

nodeProps#

AttributeDescription
data-scope"tree"
data-part"node"
data-node-keyNode key value
data-expandedPresent when node is expanded (non-leaf only)
data-collapsedPresent when node is collapsed (non-leaf only)
data-selectedPresent when node is selected
data-leafPresent when node is a leaf
data-disabledPresent when node is disabled

contentProps#

AttributeDescription
data-scope"tree"
data-part"content"
data-selectedPresent when selected or checked
data-selectablePresent when selectable
data-expandedPresent when expanded (non-leaf only)
data-collapsedPresent when collapsed (non-leaf only)
data-leafPresent when leaf node
data-checkedPresent when checked (checkbox mode)
data-partial-checkedPresent when partially checked (checkbox mode)
data-disabledPresent when disabled
data-drop-hoverPresent when a dragged node hovers over content

getToggleProps#

AttributeDescription
data-scope"tree"
data-part"toggle"
data-expandedPresent when node is expanded
data-collapsedPresent when node is collapsed

dropPointProps#

AttributeDescription
data-scope"tree"
data-part"drop-point"
[data-scope='tree'][data-part='content'] {
    padding: 0.25rem 0.5rem;
}
 
[data-scope='tree'][data-part='content'][data-selected] {
    background-color: rgba(var(--primary-rgb), 0.1);
}
 
[data-scope='tree'][data-part='content'][data-expanded] {
    font-weight: 600;
}
 
[data-scope='tree'][data-part='node'][data-node-key='0'] {
    font-weight: bold;
}

API#

useTree#

NameTypeDefault
valueTreeNodeData[]—
An array of treenodes.
expandedKeysTreeExpandedKeys—
A record of keys to represent the state of the tree expansion state in controlled mode.
defaultExpandedKeysTreeExpandedKeys—
The default expanded keys when used in uncontrolled mode.
selectionKeysTreeSelectionKeys | TreeCheckboxSelectionKeys—
A record of keys to represent the selection state in controlled mode. For single/multiple mode: Record<string, boolean> For checkbox mode: Record<string, { checked: boolean, partialChecked: boolean }>
defaultSelectionKeysTreeSelectionKeys | TreeCheckboxSelectionKeys—
The default selected keys when used in uncontrolled mode.
selectionMode"checkbox" | "multiple" | "single"—
Defines the selection mode.
metaKeySelectionbooleanfalse
Defines how multiple items can be selected, when true metaKey needs to be pressed to select or unselect multiple items. When set to false selection of each item can be toggled individually.
highlightOnSelectbooleanfalse
Highlights automatically the first item.
draggableNodesboolean—
Whether the tree nodes can be dragged.
droppableNodesboolean—
Whether the tree can accept dropped nodes.
draggableScopestring | string[]—
A unique identifier for the draggable scope.
droppableScopestring | string[]—
A unique identifier for the droppable scope.
validateDropbooleanfalse
Whether to validate drops before processing.
onExpandedChange(event: useTreeExpandedChangeEvent) => void—
Callback fired when the tree's expanded keys change.
onSelectionChange(event: useTreeSelectionChangeEvent) => void—
Callback fired when the tree's selection changes.
onToggle(event: useTreeToggleEvent) => void—
Callback fired when a node is toggled.
onExpand(event: useTreeExpandEvent) => void—
Callback fired when a node is toggled.
onCollapse(event: useTreeCollapseEvent) => void—
Callback fired when a node is toggled.
onClick(event: useTreeClickEvent) => void—
Callback fired when a node is clicked.
onSelect(event: useTreeSelectEvent) => void—
Callback fired when a node is selected.
onUnselect(event: useTreeUnselectEvent) => void—
Callback fired when a node is unselected.
onNodeDrop(event: useTreeNodeDropEvent) => void—
Callback fired when a node is dropped.
onDragEnter(event: useTreeDragEnterEvent) => void—
Callback fired when drag enters the tree.
onDragLeave(event: useTreeDragLeaveEvent) => void—
Callback fired when drag leaves the tree.
onValueChange(event: useTreeValueChangeEvent) => void—
Callback fired when the tree value changes (for drag-drop).

useTreeNode#

NameTypeDefault

Accessibility#

See Tree Primitive for WAI-ARIA compliance details and keyboard support.