如何在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
相关产品推荐
相关产品推荐

