const createTreeFromNestedSet = arr =>
[...arr].sort((a, b) => a.left - b.left).reduce((tree, n) => {
let curr = null;
let next = tree;
while (next) {
curr = next;
next = curr.children.find(c => c.left < n.left && c.right > n.right);
}
curr.children.push({ ...n, children: [] });
return tree;
}, { children: [] }).children[0];
const NestedSetTreeItem = ({ item }) => {
const [ showChildren, setShowChildren ] = React.useState(false);
const onClick = () => setShowChildren(v => !v);
return (
<div className="tree-item">
<span>{item.title}: {item.left} - {item.right}</span>
{item.children.length !== 0 ? (
<React.Fragment>
<button onClick={onClick}>{showChildren ? '-' : '+'}</button>
<div className={showChildren ? '' : 'hidden'}>
{item.children.map(n => <NestedSetTreeItem key={n.id} item={n} />)}
</div>
</React.Fragment>
) : null}
</div>
);
};
const NestedSetTree = ({ data }) => {
const tree = React.useMemo(() => createTreeFromNestedSet(data), [ data ]);
return <NestedSetTreeItem item={tree} />;
};
const data = [
{ title: 'Clothing', left: 1, right: 22 },
{ title: 'Men\'s', left: 2, right: 9 },
{ title: 'Women\'s', left: 10, right: 21 },
{ title: 'Suits', left: 3, right: 8 },
{ title: 'Slacks', left: 4, right: 5 },
{ title: 'Jackets', left: 6, right: 7 },
{ title: 'Dresses', left: 11, right: 16 },
{ title: 'Skirts', left: 17, right: 18 },
{ title: 'Blouses', left: 19, right: 20 },
{ title: 'Evening Gowns', left: 12, right: 13 },
{ title: 'Sun Dresses', left: 14, right: 15 },
].map((n, i) => ({ ...n, id: i + 1 }));
ReactDOM.render(<NestedSetTree data={data} />, document.getElementById('app'));
<div id="app"></div>