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

React.js中MUI Tree View因节点ID重复报错求助

解决MUI X TreeView重复id错误问题

问题原因

你使用的MUI X TreeView v6+版本调整了API规范:原有的TreeView组件改为无头组件,不再支持直接嵌套TreeItem的写法,必须使用SimpleTreeView(基础树形视图)或RichTreeView(增强版)来实现嵌套结构;否则会触发id未定义/重复的错误。

修复方案

方案1:切换到SimpleTreeView组件(适配原有嵌套写法)

修改TreeHierarchy.js中的导入和组件使用,同时优化id生成逻辑:

import React from "react";
// 替换原有TreeView为SimpleTreeView
import { SimpleTreeView, TreeItem } from "@mui/x-tree-view";
import ExpandMoreIcon from "@mui/icons-material/ExpandMore";
import ChevronRightIcon from "@mui/icons-material/ChevronRight";

// Sample hierarchy
const hierarchy = {
name: "Bahria",
precincts: [
{
  name: "Precinct-1",
  streets: [
    {
      name: "Road 1",
      meters: ["3092000001", "3092000210"],
    },
    {
      name: "Street 21",
      meters: ["3092000012"],
    },
    ],
    },
    ],
 };

// 递归渲染树形结构,优化id生成
const TreeHierarchy = () => {
const renderTree = (node, parentId = "root") => {
  // 用root作为初始父id,避免id以横杠开头
  const nodeId = `${parentId}-${node.name}`;

  return (
    <TreeItem key={nodeId} nodeId={nodeId} label={node.name}>
      {/* 调整顺序,先渲染precincts再渲染streets,匹配期望结构 */}
      {node.precincts &&
        node.precincts.map((precinct, index) =>
          renderTree(precinct, `${nodeId}-precinct-${index}`)
        )}
      {node.streets &&
        node.streets.map((street, index) =>
          renderTree(street, `${nodeId}-street-${index}`)
        )}
      {node.meters &&
        node.meters.map((meter, index) => (
          <TreeItem
            key={`${nodeId}-meter-${index}`}
            nodeId={`${nodeId}-meter-${index}`}
            label={`Meter: ${meter}`}
          />
        ))}
    </TreeItem>
  );
};

return (
  <SimpleTreeView
    defaultCollapseIcon={<ExpandMoreIcon />}
    defaultExpandIcon={<ChevronRightIcon />}
  >
    {renderTree(hierarchy)}
  </SimpleTreeView>
);
};

export default TreeHierarchy;

方案2:改用声明式items prop写法(v6+推荐用法)

如果你想遵循MUI X v6的最佳实践,可以将嵌套数据转换为扁平结构,配合items和getItemId prop实现:

import React from "react";
import { TreeView } from "@mui/x-tree-view";
import ExpandMoreIcon from "@mui/icons-material/ExpandMore";
import ChevronRightIcon from "@mui/icons-material/ChevronRight";

// 将嵌套层级数据转换为扁平items结构
const flattenHierarchy = (node, parentId = null, items = []) => {
  const itemId = node.name;
  items.push({
    id: itemId,
    label: node.name,
    parentId: parentId,
  });

  // 递归处理子节点
  if (node.precincts) {
    node.precincts.forEach(precinct => flattenHierarchy(precinct, itemId, items));
  }
  if (node.streets) {
    node.streets.forEach(street => flattenHierarchy(street, itemId, items));
  }
  if (node.meters) {
    node.meters.forEach(meter => {
      items.push({
        id: `meter-${meter}`,
        label: `Meter: ${meter}`,
        parentId: itemId,
      });
    });
  }
  return items;
};

const hierarchy = {
name: "Bahria",
precincts: [
{
  name: "Precinct-1",
  streets: [
    {
      name: "Road 1",
      meters: ["3092000001", "3092000210"],
    },
    {
      name: "Street 21",
      meters: ["3092000012"],
    },
    ],
    },
    ],
 };

const TreeHierarchy = () => {
  const items = flattenHierarchy(hierarchy);

  return (
    <TreeView
      items={items}
      defaultCollapseIcon={<ExpandMoreIcon />}
      defaultExpandIcon={<ChevronRightIcon />}
      getItemId={(item) => item.id}
    />
  );
};

export default TreeHierarchy;

最终效果

修复后会按照你的期望渲染树形结构:

Bahria
  => Precinct-1
      => Road 1
         => Meter: 3092000001
         => Meter: 3092000210
      => Street 21
         => Meter: 3092000012

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 15:37:04