react-sortable-tree设置treeIndex后不遵循节点排序如何解决
问题根因
getTreeFromFlatData本身不会自动根据treeIndex字段排序,它只会按照传入的flatData数组的顺序,依次将子节点挂载到对应父节点下,子节点的最终顺序就是flatData里同父级节点的出现顺序。- 你现在对所有节点做全局
treeIndex排序是错误的,treeIndex是同一父节点下的子节点相对排序值,跨父节点的treeIndex对比没有意义,全局排序会打乱不同层级节点的挂载顺序。 - 你调用
getTreeFromFlatData时没有传入getNodeKey参数,这个参数用来定义节点的唯一标识,和getParentKey配对使用,缺失会导致父子节点关联逻辑异常。
解决步骤
- 先将扁平化节点按父节点分组,每个分组内单独按
treeIndex升序排序 - 把排序后的所有节点按层级顺序拼接为新的flat数组,再传入
getTreeFromFlatData - 补充
getNodeKey参数保证父子关联正确
修正后代码
// 1. 赋值treeIndex和path的逻辑保持不变,提前缓存父节点id避免重复取值 flatTree.forEach(treeNode => { labelNodes.forEach(element => { if (treeNode.node.id === element.id) { treeNode.path = element.path; treeNode.treeIndex = element.treeIndex; treeNode.parentId = treeNode.parentNode?.id ?? 0; } }); }); // 2. 按父节点分组,同组内按treeIndex排序 const groupByParent = flatTree.reduce((res, node) => { const parentId = node.parentId; if (!res[parentId]) res[parentId] = []; res[parentId].push(node); res[parentId].sort((a, b) => a.treeIndex - b.treeIndex); return res; }, {}); // 3. 按层级拼接排序后的节点:先根节点,再依次处理各级子节点 const sortedFlatTree = []; const queue = [...(groupByParent[0] || [])]; while (queue.length) { const current = queue.shift(); sortedFlatTree.push(current); const children = groupByParent[current.node.id] || []; queue.push(...children); } // 4. 调用转换方法,补充getNodeKey参数 const treeConversion = getTreeFromFlatData({ flatData: sortedFlatTree, getParentKey: node => node.parentId, getNodeKey: node => node.node.id, });
兜底兼容方案
如果调整后仍有顺序异常,可以直接对生成的树结构做递归排序,强制每一层子节点按treeIndex排序:
const sortTreeChildren = (treeList) => { return treeList.sort((a,b) => a.treeIndex - b.treeIndex).map(node => { if (node.children?.length) { node.children = sortTreeChildren(node.children); } return node; }) } const finalTreeData = sortTreeChildren(treeConversion);
内容的提问来源于stack exchange,提问作者koro
相关产品推荐
相关产品推荐

