创建嵌套 Dom 节点结构时遇到问题

问题描述 投票:0回答:1

我正在尝试使用 React 组件的 ulli 标签创建嵌套 dom 节点结构(类似于文件夹树)。此嵌套结构基于以下代码中提供的输入数组对象的“路径”键

下面是我用来创建 dom 节点的代码

let pathArray = []
let nested = [];
let rootNode = [];

let data = [
    {
        "id": "bbc57df8b48fa010b34d3d586bcdb63e12fcc230",
        "name": "Hooks",
        "type": "tree",
        "path": "Hooks",
        "mode": "040000"
    },
    {
        "id": "bbc57df8b48fa010b34d3d586bcdb63e12fcc230",
        "name": "ab1",
        "type": "tree",
        "path": "Hooks/ab1",
        "mode": "040000"
    },
    {
        "id": "bbc57df8b48fa010b34d3d586bcdb63e12fcc230",
        "name": "ab2",
        "type": "tree",
        "path": "Hooks/ab2",
        "mode": "040000"
    },
    {
        "id": "bbc57df8b48fa010b34d3d586bcdb63e12fcc230",
        "name": "bb2",
        "type": "tree",
        "path": "Hooks/ab1/bb2",
        "mode": "040000"
    },
    {
        "id": "6d20bb276234ea4b97ee8e47a8efc5ae945cdc65",
        "name": "Routing",
        "type": "tree",
        "path": "Routing",
        "mode": "040000"
    },
    {
        "id": "23602d99d0680243f32f07410b5c227f0d0c0331",
        "name": "L1.png",
        "type": "blob",
        "path": "Hooks/L1.png",
        "mode": "100644"
    },
    {
        "id": "e89d96e5e23a7f0e7cb240b28dace2259328b3ee",
        "name": "ReadMe.md",
        "type": "blob",
        "path": "Hooks/ReadMe.md",
        "mode": "100644"
    },
    {
        "id": "e89d96e5e23a7f0e7cb240b28dace2259328b3ee",
        "name": "ab1.md",
        "type": "blob",
        "path": "Hooks/ab1/ab1.md",
        "mode": "100644"
    },
    {
        "id": "e89d96e5e23a7f0e7cb240b28dace2259328b3ee",
        "name": "ab2.md",
        "type": "blob",
        "path": "Hooks/ab2/ab2.md",
        "mode": "100644"
    },
    {
        "id": "e89d96e5e23a7f0e7cb240b28dace2259328b3ee",
        "name": "bb2.md",
        "type": "blob",
        "path": "Hooks/ab1/bb2/bb2.md",
        "mode": "100644"
    },
    {
        "id": "23602d99d0680243f32f07410b5c227f0d0c0331",
        "name": "L1.png",
        "type": "blob",
        "path": "L1.png",
        "mode": "100644"
    },
    {
        "id": "b014be6ae81b88953520d2e43c94fa403a6384f8",
        "name": "ReadMe.md",
        "type": "blob",
        "path": "Routing/ReadMe.md",
        "mode": "100644"
    },
    {
        "id": "77c1b823a94a7f3441c785ef27a072ce6db6b0e4",
        "name": "file.md",
        "type": "blob",
        "path": "file.md",
        "mode": "100644"
    },
    {
        "id": "def1f0ba9051393b4128d0ecb8d35cb4780c936c",
        "name": "test.md",
        "type": "blob",
        "path": "test.md",
        "mode": "100644"
    }
];


const createNestedDOM = (path) => {

    console.log("path : " + path)
    let array = data.filter(child => child.path.startsWith(path + '/'))


    console.log("array : " + JSON.stringify(array))
    console.log("current pathArray : " + JSON.stringify(pathArray))

    // Loop through array elements
    array.forEach((item) => {
        console.log(" Current item : " + JSON.stringify(item))

        if (!pathArray.includes(item.path)) {
            pathArray.push(item.path)

            if (item.type === "tree") {

                console.log("pushing UL path  : " + item.path)
                return (<ul key={item.path} onClick={toggleDisplay} className={`${styles.boardPageList} my-2 py-2 px-1`}>
                    <div className='d-flex justify-content-between'><span>{item.name}</span> <ChevronDown className='align-self-center' size={16} /></div>
                    {createNestedDOM(item.path)}
                </ul>);
            }
            else {

                console.log("pushing LI path : " + item.path)
                return (<li key={item.path} value={item.name} onClick={(e) => { openBoard(e, item.name) }} className={`${styles.boardPageListItem}`}>
                    {item.name}
                </li>)

            }
        }
    });
};



const createDirTree = () => {
    rootNode.forEach((item) => {

        let node = undefined;
        console.log("item from parent : " + JSON.stringify(item))
        pathArray.push(item.path)
        if (item.type === "tree") {
            node = (<ul key={item.path} onClick={toggleDisplay} className={`${styles.boardPageList} my-2 py-2 px-1`}>
                <div className='d-flex justify-content-between'><span>{item.name}</span> <ChevronDown className='align-self-center' size={16} /></div>
                {createNestedDOM(item.path)}
            </ul>)
        }
        else {
            node = (<li key={item.path} value={item.name} onClick={(e) => { openBoard(e, item.name) }} className={`${styles.boardPageListItem} my-2 py-2`}>
                {item.name}
            </li>)
        }

        console.log(node)
        nested.push(node)

    })
}


for (let index = 0; index < data.length; index++) {
    let obj = data[index]
    let arrPath = obj.path.split("/")
    if (arrPath.length == 1) {
        rootNode.push(obj)
    }
}

createDirTree()

预期结果是它应该返回 ul 元素,其中包含基于输入的嵌套路径的 ulli 元素。但执行后,“Hooks”ul

元素下没有嵌套元素

current output for hooks

正如您在上面的输出片段中看到的,“Hooks”的 ul 元素的第一个 div 子级之后的子级在我期望嵌套元素的地方未定义。

任何人都可以指导我在这里遗漏或出错的地方吗? 对于冗长的代码表示歉意。只是这件事的初学者。蒂亚!!

javascript reactjs sorting recursion jsx
1个回答
0
投票

您面临的问题在于 createNestedDOM 函数。 它目前没有显式返回任何 JSX 元素,这就是为什么您未定义为 ul 元素的子元素。

由于 Array.prototype.forEach 不返回任何内容,因此 forEach 回调中的返回值不会向上传播。

您可能不想使用 forEach,而是使用 map,它返回一个新数组,其中包含对调用数组中的每个元素调用所提供函数的结果。

如果有帮助,请尝试使用地图。

  const createNestedDOM = (path) => {
    let array = data.filter(child => child.path.startsWith(path + '/'))
    // Mapping array elements to JSX elements
    let elements = array.map((item) => {
        if (!pathArray.includes(item.path)) {
            pathArray.push(item.path)

            if (item.type === "tree") {
                return (
                    <ul key={item.path} onClick={toggleDisplay} className={`${styles.boardPageList} my-2 py-2 px-1`}>
                        <div className='d-flex justify-content-between'><span>{item.name}</span> <ChevronDown className='align-self-center' size={16} /></div>
                        {createNestedDOM(item.path)}
                    </ul>
                );
            } else {
                return (
                    <li key={item.path} value={item.name} onClick={(e) => { openBoard(e, item.name) }} className={`${styles.boardPageListItem}`}>
                        {item.name}
                    </li>
                );
            }
        }
    });

    return elements; // Return the JSX elements
     };
© www.soinside.com 2019 - 2024. All rights reserved.