Persisting the Focus on Data Reload
The TreeView enables you to keep the focus on the currently focused item while reloading the data.
Using Hierarchical Item Indices
By default, the TreeView keeps the focus through hierarchical item indices. The indices are zero-based and the first root item has a 0
(zero) index. If the first root item has children, the first child acquires a 0_0
index, the second child—a 0_1
index, and so on.
The following example demonstrates how the focused item is preserved upon constant re-rendering of the TreeView.
Using Item IDs
When you expect changes in the overall position of the TreeView items, set the focusIdField
property to a field that uniquely describes the item—for example, an ID column from a database. The field id is not affected by position changes and the TreeView will be able to persist the focus on the current item.
The following example demonstrates how to add an item on every click before the clicked item and keep the focus on changing the item position. On each re-render, the TreeView executes a depth-first data search to resolve the focused item by its id because of possible position changes. For an additional optimization, set the getFocusHierarchicalIndex
property to a custom function which will resolve a hierarchical item index by its id. For example, you can use cache
which will be invalidated on each data reload.
const tree = [{
text: 'Furniture', expanded: true, items: [
{ text: 'Tables & Chairs' }, { text: 'Sofas' }, { text: 'Occasional Furniture' }]
}, {
text: 'Decor', expanded: true, items: [
{ text: 'Bed Linen' }, { text: 'Curtains & Blinds' }, { text: 'Carpets' }]
}];
class App extends React.Component {
addedItemsCounter = 0;
state = { data: tree };
render() {
return <TreeView focusIdField='text' data={this.state.data} onItemClick={this.onItemClick} />;
}
onItemClick = (event) => {
const data = this.state.data.slice();
if (data.includes(event.item)) {
data.unshift({ text: `added item #${this.addedItemsCounter++}` });
} else {
const parentIndex = data[data.length - 1].items.includes(event.item) ?
data.length - 1 : data.length - 2;
data[parentIndex] = Object.assign(
{},
data[parentIndex],
{ items: data[parentIndex].items.slice() }
);
data[parentIndex].items.unshift({ text: `added item #${this.addedItemsCounter++}` });
}
this.setState({ data });
}
}
ReactDOM.render(
<App />,
document.querySelector('my-app')
);