I'm building a TreeView
with the Treeview component from Material UI: https://material-ui.com/components/tree-view/
I have created the component below which fetches data when a node is expanded. Furthermore, the tree is build so each node that have children also is a tree, but I have two questions:
Question 1:
Right now the fetchChildNodes
gets called each time a node is expanded. I want to change this so that i'm checking if the current node has been expanded before. If it has been expanded I don't want to call fetchChildNodes
, but use the data fetched earlier. This is because I for a node can expand, close, and expand again, and the fetchChildNodes
will in this process be called twice. How can I check this?
Question 2:
Is there some kind of onClick
method that can provide the nodeId
for the node clicked? The expandingNodes
only provides nodeId
for expandable nodes and not leaf
nodes.
import ReactDOM from react-dom;
import React from react;
import TreeView from @material-ui/lab/TreeView;
import ExpandMoreIcon from @material-ui/icons/ExpandMore;
import ChevronRightIcon from @material-ui/icons/ChevronRight;
import TreeItem from @material-ui/lab/TreeItem;
const { useState, useCallback } = React;
export default function MyTreeItem(props) {
const [childNodes, setChildNodes] = useState(null);
const [expanded, setExpanded] = React.useState([]);
function fetchChildNodes(id) {
return new Promise(resolve => {
setTimeout(() => {
resolve({
children: [
{
id: 2,
name: Calendar
},
{
id: 3,
name: Settings
},
{
id: 4,
name: Music
}
]
});
}, 1000);
});
}
const handleChange = (event, nodes) => {
const expandingNodes = nodes.filter(x => !expanded.includes(x));
setExpanded(nodes);
if (expandingNodes[0]) {
const childId = expandingNodes[0];
fetchChildNodes(childId).then(result =>
setChildNodes(
result.children.map(node => <MyTreeItem key={node.id} {...node} />)
)
);
}
};
return (
<TreeView
defaultCollapseIcon={<ExpandMoreIcon />}
defaultExpandIcon={<ChevronRightIcon />}
expanded={expanded}
onNodeToggle={handleChange}
>
{/*The node below should act as the root node for now */}
<TreeItem nodeId={props.id} label={props.name}>
{childNodes || [<div key=stub />]}
</TreeItem>
</TreeView>
);
}
const rootElement = document.getElementById(root);
ReactDOM.render(<MyTreeItem id=1 name=Applications />, rootElement);