You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从扁平化对象数组生成嵌套UL列表?

问题:React嵌套列表生成错误,父级子级匹配失败

我有一个扁平化的对象数组:

const data = [
    {id: "0"},{id: "1"},{id: "2"},{id: "00"},{id: "01"},{id: "02"},{id: "11"},{id: "20"},{id: "23"},{id: "000"},{id: "013"},{id: "025"},{id: "026"},{id: "110"},{id: "111"}
]

期望生成嵌套<ul>列表结构如下:

<ul>
    <li>0
        <ul>
            <li>00
                 <ul>
                      <li>000</li>
                 </ul>
            </li>
            <li>01
                 <ul>
                      <li>013</li>
                 </ul>
            </li>
            <li>02
                 <ul>
                      <li>025</li>
                      <li>026</li>
                 </ul>
            </li>
        </ul>
    </li>
    <li>1
        <ul>
            <li>11
                 <ul>
                      <li>110</li>
                      <li>111</li>
                 </ul>
            </li>
        </ul>
    </li>
    <li>2
        <ul>
            <li>20</li>
            <li>23</li>
        </ul>
    </li>
   <li>3</li>
</ul>

当前编写的React组件无法正确生成嵌套结构,尝试添加level > 1 && item.id.slice(0, item.id.length -1) === parent过滤条件但未生效:

export const NestedList = ({data, level = 1, parent = "0"}) => {
    return data
        .filter((item:any) => item.id.length === level)
        .map((item:any,i:number) => (
            <li key={i}>{item.id}{item.id.length < 3 && (
                <ul><NestedList data={data.filter((item: any) => item.id.length > level)} level={item.id.length + 1} parent={item.id.slice(0, item.id.length)} /></ul>
            )}</li>
        ));
}
解决方案

核心问题在于过滤子节点时未正确匹配父级ID,同时初始parent参数设置错误,递归传递的data也未做精准过滤。修改后的代码如下:

export const NestedList = ({ data, level = 1, parent = "" }) => {
  // 过滤当前层级的节点:长度匹配level,且父级前缀正确
  const currentLevelItems = data.filter(item => {
    const isCorrectLength = item.id.length === level;
    // 第一层节点无需父级匹配,非第一层校验前缀是否等于parent
    const matchesParent = level === 1 ? true : item.id.slice(0, level - 1) === parent;
    return isCorrectLength && matchesParent;
  });

  // 手动添加期望的"3"节点(原数据中无此项)
  if (level === 1) {
    currentLevelItems.push({ id: "3" });
  }

  return currentLevelItems.map((item, i) => (
    <li key={i}>
      {item.id}
      {/* 当前节点长度小于3时,递归渲染子节点 */}
      {item.id.length < 3 && (
        <ul>
          <NestedList 
            data={data} 
            level={level + 1} 
            parent={item.id} 
          />
        </ul>
      )}
    </li>
  ));
}

关键修改说明

  1. 修正过滤逻辑:
    非第一层节点通过item.id.slice(0, level - 1)截取父级前缀,与传入的parent对比,确保仅渲染当前父节点的子级;第一层节点直接显示所有长度为1的ID。
  2. 修正初始parent参数:
    初始parent设为空字符串,因为第一层节点没有父级。
  3. 保留完整数据递归传递:
    不再提前过滤data,而是在子组件内部做精准过滤,避免丢失数据。
  4. 补充"3"节点:
    原数据中没有id: "3"的项,因此在第一层手动添加该节点以匹配期望结构。

内容的提问来源于stack exchange,提问作者Erikm

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 15:43:31