Home > Mobile >  Render tree items recursively React
Render tree items recursively React

Time:11-03

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>

  • Related