类Wix拖拽布局:如何通过递归基于depthInfo生成React组件树?
基于depthInfo递归生成React组件树的实现方法
我正在做类似Wix的拖拽布局功能,支持拖拽组件、调整属性生成自定义布局。组件用嵌套JSON存储,需要通过中间结构depthInfo递归生成对应的React组件树。
现有数据结构示例
depthInfo结构
const depthInfo = [ {1 : {params: ['div', null], Id: "gbKyzEom"}}, {2: {params: ["span", null], id: "hrykbdm", parentId:"gbKyzEom" }}, {2: {params: ["h1", null], id: "opeFbVcd", parentId:"gbKyzEom" }} ];
目标生成的React组件树
React.createElement.apply(null, [ 'div', null, React.createElement.apply(null, ['span', null]), React.createElement.apply(null, ['h1', null]) ])
实现步骤与代码
1. 预处理depthInfo,构建组件映射与父子关系
先把扁平的depthInfo转换成便于递归遍历的结构,建立组件ID到组件数据的映射,以及父ID到子ID列表的映射:
const processDepthInfo = (depthInfo) => { const componentMap = {}; const childrenMap = {}; depthInfo.forEach(item => { // 取出每个项中的组件数据(每个item是单键对象,键为深度值) const [, componentData] = Object.entries(item)[0]; const id = componentData.Id || componentData.id; // 兼容ID字段大小写不一致的情况 componentMap[id] = { ...componentData }; const parentId = componentData.parentId; if (parentId) { childrenMap[parentId] = childrenMap[parentId] || []; childrenMap[parentId].push(id); } }); // 筛选出根组件(无parentId的组件) const rootIds = Object.keys(componentMap).filter(id => !componentMap[id].parentId); return { componentMap, childrenMap, rootIds }; };
2. 递归生成React组件树
通过递归函数,从根组件开始,依次构建每个组件及其子组件:
const buildReactTree = (componentId, componentMap, childrenMap) => { const { params } = componentMap[componentId]; const [tag, props] = params; // 递归生成所有子组件 const childElements = (childrenMap[componentId] || []).map(childId => buildReactTree(childId, componentMap, childrenMap) ); // 用apply方式调用React.createElement,组装当前组件 return React.createElement.apply(null, [tag, props, ...childElements]); };
3. 使用示例
// 处理depthInfo const { componentMap, childrenMap, rootIds } = processDepthInfo(depthInfo); // 生成组件树(示例中只有一个根组件,直接取第一个) const reactTree = buildReactTree(rootIds[0], componentMap, childrenMap);
关键注意事项
- 兼容depthInfo中ID字段的大小写差异(示例中存在
Id和id两种写法) - 若存在多个根组件,需遍历
rootIds生成多个组件节点 - 当
props为null时,React.createElement会自动处理为无额外属性的组件
内容的提问来源于stack exchange,提问作者vrn
相关产品推荐
相关产品推荐

