I'm trying to render tree items recursively with React but I can't quite get the desired result I want. I know the problem is with calling treeRender(children)
as it changes the data structure on the first instance of a folder. I wonder how this is being done properly.
My attempt:
const treeRender = (data: any) => {
for (const [name, value] of Object.entries(data)) {
if (typeof value == "object") {
const children = value
return (
<StyledTreeItem
key={name}
nodeId={name}
labelText={name}
labelIcon={FolderIcon}
>
{treeRender(children)}
</StyledTreeItem>
);
} else {
return (
<StyledTreeItem
key={name}
nodeId={name}
labelText={name}
labelIcon={InsertDriveFileIcon}
/>
);
}
}
};
return (
<TreeView
aria-label={"filePicker"}
defaultExpanded={["3"]}
defaultCollapseIcon={<ArrowDropDownIcon />}
defaultExpandIcon={<ArrowRightIcon />}
defaultEndIcon={<div style={{ width: 24 }} />}
sx={{ height: 264, flexGrow: 1, maxWidth: 400, overflowY: "auto" }}
>
{treeRender(fileTree)}
</TreeView>
);
The output is only rendering the first folder and file level instead of rendering all the folders:
{
"__global": {
"globalFile.csv": "download link"
},
}
Desired rendered output (This is the input data as well):
{
"__global": {
"globalFile.csv": "download link"
},
"group1": {
"folder": {
"folderFile.csv": "download link"
},
"group1File.csv": "download link"
}
}
CodePudding user response:
the return
will exit the loop on the first iteration and won't go to the next elements, you should store the elements inside a variable and return it after the loop is finished, see the snippet below for a simplified version of your code : ( replace div
with StyledTreeItem
)
const input = {
"__global": {
"globalFile.csv": "download link"
},
"group1": {
"folder": {
"folderFile.csv": "download link"
},
"group1File.csv": "download link"
}
}
const treeRender = (data) => {
const result = [];
for (const [name, value] of Object.entries(data)) {
if (typeof value == "object") {
const children = value
result.push(
<div key={name}>{treeRender(children)}</div>
);
} else {
result.push(
<div key={name}>{name}</div>
);
}
}
return result;
};
ReactDOM.render(<div>{treeRender(input)}</div>, document.querySelector("#root"))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root"></div>