You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React JS递归处理数据触发RangeError: Maximum call stack size exceeded

栈溢出报错的核心成因

你的递归终止逻辑本身设计方向是对的,但有三类问题会导致递归无法正常终止,最终触发RangeError:

  • 原始层级数据存在环形关联/自引用
    这是最常见的栈溢出诱因:如果数据中出现节点自环(单个节点的父id等于自身id)、多节点闭环(比如A的父是B,B的父是A),每次执行filter查找子节点时,都能匹配到至少一个关联项,递归会无限向下嵌套调用,直到JS引擎的调用栈被占满。
    举个最简单的触发例子:只要数据里存在{id:1, name:'a', idfather:1}这类自引用节点,代码每跑一次递归就会把自己作为子节点再次传入,永远碰不到“无匹配子节点”的终止分支。
  • 代码字段拼写前后完全不统一
    你在三处涉及父id关联的位置用了完全不同的字段名,没有任何一致性:
    • 读取原数据父id时:写的是data.idfahter(将father错拼为fahter,少了字母t)
    • 给结果对象赋值父id时:写的是idfhater(将idFather错拼为idfhater,多了字母h、漏了结尾的r)
    • 查找子节点做相等判断时:写的是item.idfather(使用了全小写的idfather命名)
      如果原始数据的父id字段和你filter判断用的字段名不一致,会导致匹配逻辑完全失效;如果字段名匹配错误意外让本不该被识别为子节点的项被筛出来,也会打破递归终止条件。
  • 额外的非报错类功能bug
    你目前的代码在拿到递归返回值时,是把整个子节点数组作为一个独立元素push到结果里,最终生成的是多层嵌套的数组结构,不是你预期的带缩进的平铺节点列表,只不过这个问题不会导致栈溢出。
可直接落地的修正方案
  • 前置数据校验:在正式递归处理前,先遍历全量节点,排查自环、跨节点成环的异常数据,从源头避免无限递归。
  • 统一字段命名:把所有涉及父id的字段名做统一(比如全部用idFather作为键名),保证读取、存储、匹配逻辑用的是同一个字段。
  • 修正递归结果的合并逻辑:用展开运算符把递归返回的子节点列表合并到当前结果数组中,避免生成嵌套结构。
  • 可选兜底方案:如果业务场景下原始数据不可控,可以增加递归深度参数,当深度超过合理阈值(比如100层,远大于常规业务的层级数)时自动终止递归,避免栈溢出。

修正后的参考代码:

function orderRecursive(Data, tab = "") {
    let orderData = [];
    for (const data of Data) {
        orderData.push({  
            id : data.id,
            name: tab + data.name,
            idFather : data.idFather // 统一字段拼写
        });  

        // 统一字段后做子节点匹配
        const children = Data.filter(item => item.idFather === data.id);         
        if(children.length > 0) {           
            // 展开递归结果,避免嵌套数组
            orderData.push(...orderRecursive(children, tab + "\t"));
        }
    }    
    return orderData;
}

内容的提问来源于stack exchange,提问作者user15242898

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.22 16:27:04