服务端组件调用异步函数触发栈溢出错误:原因与修复
错误原因与修复方案
错误根源
- 数据传递结构错误:你的
getData函数返回了{ props: { data } }结构,但Page组件直接将整个返回值传给了CsvDownloader,实际需要的是嵌套在props里的data数据。 - Mongoose文档的循环引用:
db.find({})返回的是Mongoose文档对象,这类对象包含大量内部属性(如Mongoose的方法、原型链引用),且存在循环引用关系。react-csv的CSVLink在序列化数据时会递归遍历对象属性,无限递归导致栈溢出。
修复步骤
步骤1:修正数据传递结构
修改getData函数的返回值,直接返回查询到的数据(无需包裹props结构,Next.js 13+的异步Page组件不需要旧版数据获取函数的返回格式),同时在Page组件中正确接收数据。
步骤2:将Mongoose文档转为纯JS对象
使用Mongoose的lean()方法,在查询时直接返回纯JavaScript对象,避免携带Mongoose的内部属性和循环引用。
修改后的page.tsx代码:
import CsvDownloader from "./csv-link"; import mongoose from "mongoose"; import db from "./dbSchema"; export async function getData() { await mongoose.connect( "mongodb+srv://<acccount>:<passowrd>@xyz.mongodb.net/?retryWrites=true&w=majority", { dbName: "exmapledbName", } ); // 使用lean()获取纯JS对象,消除Mongoose文档的循环引用 const data = await db.find({}).lean(); return data; } export default async function Page() { const data = await getData(); return ( <div> <CsvDownloader data={data} /> </div> ); }
替代方案(不使用lean())
如果无法使用lean(),可以将查询到的Mongoose文档逐个转换为纯对象:
// 在getData函数中替换查询语句 const dataDocs = await db.find({}); const data = dataDocs.map(doc => doc.toObject()); return data;
验证修复
修改后,CsvDownloader接收的是纯JS数组对象,react-csv可以正常序列化数据,不会出现递归无限调用的情况,栈溢出错误即可解决。
内容的提问来源于stack exchange,提问作者TungTung
相关产品推荐
相关产品推荐

