我正在尝试使用 React 组件的 ul 和 li 标签创建嵌套 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 元素,其中包含基于输入的嵌套路径的 ul 和 li 元素。但执行后,“Hooks”的ul
元素下没有嵌套元素正如您在上面的输出片段中看到的,“Hooks”的 ul 元素的第一个 div 子级之后的子级在我期望嵌套元素的地方未定义。
任何人都可以指导我在这里遗漏或出错的地方吗? 对于冗长的代码表示歉意。只是这件事的初学者。蒂亚!!
您面临的问题在于 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
};