Monday, May 20, 2024
 Popular · Latest · Hot · Upcoming
112
rated 0 times [  115] [ 3]  / answers: 1 / hits: 11715  / 5 Years ago, thu, december 26, 2019, 12:00:00

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);


More From » reactjs

 Answers
10

Answering Question 2:



just add custom label object to TreeItem :



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} />
))
)
);
}
};

const renderLabel = item => (
<span
onClick={event => {
console.log(item.id);
//setActiveItemId(item.id);
// if you want after click do expand/collapse comment this two line
event.stopPropagation();
event.preventDefault();
}}
>
{item.name}
</span>
);

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={renderLabel(props)}>
{childNodes || [<div key=stub />]}
</TreeItem>
</TreeView>
);
}
const rootElement = document.getElementById(root);
ReactDOM.render(
<MyTreeItem id=1 name=Applications />,
rootElement
);


onclick


[#5230] Sunday, December 22, 2019, 5 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
harleyaleenag

Total Points: 678
Total Questions: 121
Total Answers: 105

Location: Papua New Guinea
Member since Thu, Jul 9, 2020
4 Years ago
harleyaleenag questions
Thu, May 5, 22, 00:00, 2 Years ago
Wed, Aug 19, 20, 00:00, 4 Years ago
;