-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[tree view] Add Lazy loading for tree items #9687
Comments
@KamalAman shares an interesting solution in mui/material-ui#17479 (comment). |
Is there any action on this one? I'm trying to implement a file tree view for a electron project so lazy loading is pretty necessary. 😄 |
@EloB The component lazy mount its children in the DOM. I would expect that you can create 10,000 TreeItem React elements with almost no performance implication. Is it accurate? However, the data fetching part might be an issue. We might be able to improve the component to provide lower-level primitives to handle it. For instance, a loading state as well as an event to trigger the data fetching? What are you struggling with? With @joshwooding, we were talking of making a high-level version of the component, for enterprise, that can query from REST, GraphQL or OData outside of the box. This seems like a downstream problem we would need to fix. |
@oliviertassinari Thanks for your response. I think my problem was that I made a component that returned a React fragment of TreeItem's. I think that is broken at the moment. Using component that returns a <TreeView>
<Branch path={pathOnDisk} />
</TreeView> Like this the key navigation was not working etc. const Branch = () => (
<>
<TreeItem nodeId={1} label="One" />
<TreeItem nodeId={2} label="Two" />
</>
) |
We currently have a file tree view in our application as well and I tried replacing our hand-rolled tree view with the Material-UI There was really only 1 problem I had using Because there is no way to indicate whether a node is expandable or not (Folder or File), and the expandIcon won't appear until a So, for each Folder node that appears, I would have to make a request for each of them in order for the user to be able to expand each Folder that appears further. This causes the Ultimately I think it's less about the performance of rendering many Hope this helps - I'm happy to provide an example if anyone would like one. Visually speaking the component looks great though! |
@hibearpanda I've also had problem with that. For instance if a directory was empty then it wasn't expandable. I've solved that with adding a |
Has there been a solution or workaround for this issue? Looks like a suitable candidate for deferred/lazy loading would be onNodeToggle? |
I am trying to do something similar and I cannot seem to get the second level TreeItems to display when I am lazy loading the children at each level. Here is a demo with the issue I am facing. |
my approach was to iterate with parent elements on each node expandsion const Tree = ({ listToRender }) => {
const [childNodes, setChildNodes] = useState([]);
const [expandedData, setExpandedData] = useState([]);
const [expanded, setExpanded] = useState([]);
const [nodeDataLoading, setNodeDataLoading] = useState(false);
const [currentlyExpandingNode, setCurrentlyExpandingNode] = useState(null);
useEffect(() => {
(async () => {
setChildNodes(listToRender);
setExpandedData(listToRender);
})();
}, [listToRender]);
/**
* Transform flat array of objects into tree.
* @param {(Array|Object)} dataset Tree items.
* @returns {JSX.Element} Element.
*/
const toTree = (dataset) => {
const hashTable = Object.fromEntries(
dataset.map((aData) => [aData.id, { ...aData, children: [] }])
);
const dataTree = [];
dataset.forEach((aData) => {
if (aData.parents[0])
hashTable[aData.parents[0]].children.push(hashTable[aData.id]);
else dataTree.push(hashTable[aData.id]);
});
return dataTree;
};
/**
* Render a tree.
* @param {Event} event Toggle event.
* @param {(Array|Object)} nodes Tree items.
*/
const handleChange = async (event, nodes) => {
const [nodeId] = nodes.filter((x) => !expanded.includes(x));
setNodeDataLoading(true);
setCurrentlyExpandingNode(nodeId);
if (nodeId) {
const fetchChildren = await TreeAPI.get();
const uniqueExpandedData = [...expandedData, ...fetchChildren].filter(
(
(
set // store the set and return the actual callback
) =>
(o) =>
set.has(o.id) ? false : set.add(o.id)
)(new Set()) // use an IIFE to create a Set and store it set
);
setExpandedData(uniqueExpandedData);
setChildNodes(await toTree(uniqueExpandedData));
setNodeDataLoading(false);
}
setExpanded(nodes);
return (
<>
<TreeView
className={classes.tree}
defaultCollapseIcon={
<MaterialIcon icon="expand_more" label="Collapse" />
}
defaultExpandIcon={
<MaterialIcon icon="chevron_right" label="Expand" />
}
onNodeToggle={handleChange}
>
{renderTree(childNodes)} //children rendering
</TreeView>
</>
);
};
}; |
The package mui-lazy-tree-view I implemented to solve this problem. |
In https://mui.com/blog/mui-x-v8-alpha-zero/ we communicated that MUI X v8.0 aims to include this issue. |
This issue has been closed. If you have a similar problem but not exactly the same, please open a new issue. Note @ZNackasha How did we do? Your experience with our support team matters to us. If you have a moment, please share your thoughts in this short Support Satisfaction survey. |
Summary 💡
Add the ability for TreeView to simply ask for the children of a node when a node is expanded. This will help users who have a very large tree and don't have the ability to grab all the data.
Examples 🌈
I'm proposing the addition of three callbacks props to TreeView.
isNodeExpandable called with the nodeId to determine if a node can be expanded
onNodeCollapsed is called when a nodeId that is collapsed.
onNodeExpanded called with the nodeId that is expanded. If the user returns nodes then they are treated as the children of the nodeId.
Motivation 🔦
I'm making a file lookup tree dialog for a project and did not want to request every single file/directory on the server since there is a large amount. Having isNodeExpandable allows for a quick is directory request without having to grab all the files in the directory.
The text was updated successfully, but these errors were encountered: