使用递归渲染虚拟树:函数存在parent变量重置bug,需重新实现
虚拟树递归渲染问题修复
给定如下类虚拟树结构,需要递归遍历所有分支并按内部层级渲染DOM元素,但现有渲染函数因全局parent变量无法正确重置,导致DOM层级渲染错误,需重新设计递归逻辑解决该问题。
原始虚拟树结构
const tree = { type: 'component', children: [ { type: 'host', tag: 'div', children: 'div content', }, { type: 'component', children: [ { type: 'host', tag: 'div', children: [ { type: 'host', tag: 'span', children: 'span content' }, { type: 'host', tag: 'span', children: 'span content' }, ] } ] }, { type: 'host', tag: 'div', children: 'div content', } ] }
存在bug的渲染函数
let parent = null; function renderTree(tree) { const treeBox = document.getElementById('tree'); for (const key in tree) { const value = tree[key]; if (key === 'children') { } if (Array.isArray(value)) { renderTree(value); } if (!Array.isArray(value) && typeof value === "object") { if (value.type !== "component") { let isNested = false; const element = document.createElement(value.tag); if (parent) { parent.appendChild(element); } else { treeBox.appendChild(element); } if (Array.isArray(value.children)) { isNested = !isNested; parent = element; } if (!Array.isArray(value.children)) { element.textContent = value.children; } // if(isNested == false) { // parent = null; // } } renderTree(value) } } } renderTree(tree);
问题根源与修复方案
问题出在全局parent变量:递归过程中全局变量会被所有调用共享,导致父容器上下文混乱,无法正确回溯层级。正确的做法是将父容器作为参数传入递归函数,让每个递归调用拥有独立的父上下文。
修复后的渲染函数
function renderTree(node, parentContainer) { // 处理数组类型的节点(比如children数组) if (Array.isArray(node)) { node.forEach(child => renderTree(child, parentContainer)); return; } // 跳过component类型节点,直接处理其子元素 if (node.type === 'component') { renderTree(node.children, parentContainer); return; } // 处理host类型节点:创建DOM元素 if (node.type === 'host') { const element = document.createElement(node.tag); // 处理文本子节点 if (typeof node.children === 'string') { element.textContent = node.children; } // 处理子元素节点,递归渲染并传入当前元素作为父容器 else if (Array.isArray(node.children)) { renderTree(node.children, element); } // 将创建好的元素添加到父容器 parentContainer.appendChild(element); } } // 初始化调用,传入根容器 const treeBox = document.getElementById('tree'); renderTree(tree, treeBox);
修复逻辑说明
- 移除全局
parent变量,改用递归参数传递父容器,确保每个层级的父上下文独立 - 分类型处理节点:
- 数组类型:遍历每个子节点,复用当前父容器递归渲染
component类型:直接递归处理其children,不创建DOM元素host类型:创建对应DOM元素,根据children类型(文本/数组)分别处理,数组类型递归时传入当前元素作为父容器
- 初始化调用时传入根容器
treeBox,明确渲染的起始位置
内容的提问来源于stack exchange,提问作者quester
相关产品推荐
相关产品推荐

