React实现父子层级数据点击展开:子节点无法显示子项求助
问题分析与解决方案
你的代码无法展开嵌套子节点(比如id=2的节点),核心问题出在convertToTree函数的树形结构转换逻辑上:当前实现仅将顶层父节点(parent=null)存放在tree对象的根层级,子节点仅作为顶层节点的children元素存在,没有在全局节点映射中建立独立引用。当处理更深层的子节点(比如id=3,parent=2)时,找不到对应的父节点引用,导致该父节点的children数组始终为空。
修正后的代码实现
1. 正确的树形结构转换函数
function convertToTree(data: any) { // 建立所有节点的映射表,确保每个节点都有独立引用和初始化的children数组 const nodeMap: Record<string, any> = {}; data.forEach(item => { nodeMap[item.id] = { ...item, children: [] }; }); // 构建完整树形结构 const treeRoots: any[] = []; data.forEach(item => { if (item.parent === null) { // 顶层节点直接加入根数组 treeRoots.push(nodeMap[item.id]); } else { // 将子节点挂载到对应父节点的children中 nodeMap[item.parent].children.push(nodeMap[item.id]); } }); return treeRoots; }
2. 保持TreeNode组件不变
function TreeNode({ data }: any) { const [isVisible, setIsVisible] = useState(false); const handleClick = () => { setIsVisible(!isVisible); }; return ( <div> <p onClick={handleClick}>{data.text}</p> {isVisible && data.children && data.children.length > 0 && ( <ul> {data.children.map((child: any) => ( <li key={child.id}> <TreeNode data={child} /> </li> ))} </ul> )} </div> ); }
3. 父组件中使用方式
const data = [ { id: 1, text: 'hello', parent: null }, { id: 2, text: 'hello2', parent: 1 }, { id: 3, text: 'hello3', parent: 2 }, { id: 4, text: 'where are u?', parent: null }, ]; const treeData = convertToTree(data); // 渲染树形结构 return ( <div> {treeData.map(node => ( <TreeNode key={node.id} data={node} /> ))} </div> );
逻辑说明
- 先通过
nodeMap为每个节点创建独立引用,确保后续操作的是同一个节点对象。 - 遍历数据时,将子节点准确挂载到其父节点的
children数组中,保证整个树形结构的层级关联性。 - 最终返回顶层节点数组,直接遍历渲染即可实现多层级的展开/折叠功能。
内容的提问来源于stack exchange,提问作者hasangkz
相关产品推荐
相关产品推荐

