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

如何在React JS中渲染父子关系嵌套对象数组为可展开树形结构

React实现可展开嵌套树形结构

核心思路

利用递归组件渲染嵌套的节点结构,通过React状态管理每个节点的展开/折叠状态,点击节点时切换状态并控制子节点的显示/隐藏。

完整代码实现

首先修正你提供的数据源语法错误(原代码存在多余符号):

const family = [
  {
    "data": {"id":"John", "age": 90},
    "children": [
      {
        "data": {"id":"Mary", "age": 60},
        "children": [
          {"data": {"id":"Mercy", "age": 45}} 
        ]
      },
      {
        "data": {"id":"Paul", "age": 60}
      },
      {
        "data": {"id":"Dolores", "age": 55}
      }
    ]
  }
];

接下来实现树形组件:

import { useState } from 'react';

// 树形节点子组件
const TreeNode = ({ node, expandedNodes, toggleExpand }) => {
  const hasChildren = node.children && node.children.length > 0;
  const isExpanded = expandedNodes.includes(node.data.id);

  const handleClick = () => {
    if (hasChildren) {
      toggleExpand(node.data.id);
    }
  };

  return (
    <div className="tree-node">
      <div className="node-header" onClick={handleClick}>
        {/* 展开/折叠按钮,只有有子节点时显示 */}
        {hasChildren && (
          <span className="expand-icon">{isExpanded ? '▼' : '▶'}</span>
        )}
        {/* 节点内容 */}
        <span>{node.data.id} (年龄: {node.data.age})</span>
      </div>
      {/* 子节点容器,展开时显示 */}
      {isExpanded && hasChildren && (
        <div className="children-container">
          {node.children.map(child => (
            <TreeNode 
              key={child.data.id} 
              node={child} 
              expandedNodes={expandedNodes} 
              toggleExpand={toggleExpand} 
            />
          ))}
        </div>
      )}
    </div>
  );
};

// 树形结构主组件
const TreeView = ({ data }) => {
  // 用数组存储所有展开的节点ID
  const [expandedNodes, setExpandedNodes] = useState([]);

  const toggleExpand = (nodeId) => {
    setExpandedNodes(prev => 
      prev.includes(nodeId) 
        ? prev.filter(id => id !== nodeId) 
        : [...prev, nodeId]
    );
  };

  return (
    <div className="tree-view">
      {data.map(rootNode => (
        <TreeNode 
          key={rootNode.data.id} 
          node={rootNode} 
          expandedNodes={expandedNodes} 
          toggleExpand={toggleExpand} 
        />
      ))}
    </div>
  );
};

// 使用组件
function App() {
  return (
    <div className="App">
      <TreeView data={family} />
    </div>
  );
}

export default App;

样式优化(添加CSS)

给树形结构加上缩进和交互样式,让层级更清晰:

.tree-view {
  padding: 10px;
  font-family: Arial, sans-serif;
}

.tree-node {
  margin: 4px 0;
}

.node-header {
  display: flex;
  align-items: center;
  gap: 8px;
  cursor: pointer;
  padding: 4px;
  border-radius: 4px;
}

.node-header:hover {
  background-color: #f0f0f0;
}

.expand-icon {
  font-size: 12px;
  color: #666;
}

.children-container {
  margin-left: 24px;
  border-left: 1px dashed #ddd;
  padding-left: 12px;
}

实现效果说明

  • 带有子节点的节点左侧会显示展开/折叠箭头,点击节点(或箭头)即可切换子节点的显示状态
  • 子节点会自动缩进,通过虚线边框区分层级
  • 鼠标悬停节点时会高亮,提升交互体验

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 21:40:21