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

客户端组件调用Server Function触发栈溢出错误求助

解决React客户端组件调用Server Action时的栈溢出问题

问题原因

你遇到的maximum call stack size exceeded错误,核心原因是Mongoose查询返回的是带循环引用的文档对象,而非普通JavaScript对象。这些Mongoose文档包含大量内部方法和原型链引用,当Server Action将其返回给客户端时,序列化过程会因循环引用无限递归,最终导致调用栈溢出。

而服务端组件直接调用时,React Server Components在服务端处理这些对象,无需完整序列化到客户端;返回硬编码普通对象时不存在循环引用,因此都能正常运行。

解决方案

只需将Mongoose查询结果转换为普通JavaScript对象,消除循环引用即可,有两种常用方式:

方式1:使用.lean()查询(推荐)

.lean()是Mongoose内置方法,直接返回原生JS对象,跳过Mongoose文档实例的创建,性能更优:

修改@/actions/loads.js:

"use server"

import connect from "@/helpers/db"
import Loaddata from "@/models/loaddata"

export async function getLoad(id) {
    await connect()

    if (id) {
        // 使用lean()返回普通JS对象
        const data = await Loaddata.findById(id).lean()
        return data
    }

    // 使用lean()返回普通JS对象数组
    const data = await Loaddata.find({}).lean()
    return data
}

方式2:使用.toObject()转换已有文档

如果无法使用.lean(),可以将查询得到的Mongoose文档转换为普通对象:

修改@/actions/loads.js:

"use server"

import connect from "@/helpers/db"
import Loaddata from "@/models/loaddata"

export async function getLoad(id) {
    await connect()

    if (id) {
        const data = await Loaddata.findById(id)
        // 将Mongoose文档转为普通对象
        return data.toObject()
    }

    const data = await Loaddata.find({})
    // 对数组中每个文档执行转换
    return data.map(doc => doc.toObject())
}

验证

修改后重新调用Server Action,客户端组件就能正常接收和渲染数据,不会再出现栈溢出错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 06:50:05