Mongoose操作MongoDB添加对象数组时栈溢出及前端展示异常
解决Mongoose嵌套数组导致React Table栈溢出的问题
问题原因
出现Maximum call stack size exceeded错误的核心原因是:Mongoose查询返回的不是纯JavaScript对象,而是带有内部方法和循环引用的Mongoose文档实例(包括嵌套的testcases子文档)。React Table在渲染时会深层遍历数据对象,触发这些循环引用,导致无限递归调用,最终栈溢出。
另外,如果你的columns配置中直接渲染testcases数组(未做格式化处理),React尝试渲染复杂对象时也会触发深层遍历,加剧这个问题。
解决方案
1. 服务端返回纯JSON数据
在查询Mongoose数据时,使用.lean()方法,让Mongoose直接返回普通JS对象,而非带包装的文档实例:
// 服务端查询代码示例 const questions = await Question.find().lean(); res.json(questions);
如果无法使用.lean()(比如需要保留文档方法),也可以在发送响应前将文档转为纯JSON:
const questions = await Question.find(); const plainQuestions = questions.map(question => question.toJSON()); res.json(plainQuestions);
2. 前端正确配置React Table的列渲染
确保columns中针对testcases列做格式化处理,避免直接渲染数组/对象:
// 示例columns配置 const columns = [ { accessorKey: 'title', header: '题目标题' }, { accessorKey: 'difficulty', header: '难度' }, { accessorKey: 'testcases', header: '测试用例', // 方案1:显示测试用例数量 cell: ({ value }) => `${value.length} 个`, // 方案2:格式化显示每个测试用例 // cell: ({ value }) => ( // <div className="flex flex-col gap-2"> // {value.map((tc, idx) => ( // <div key={idx} className="text-xs"> // 输入: {tc.input} → 预期输出: {tc.expectedOutput} // </div> // ))} // </div> // ) }, // 其他列... ];
3. 额外检查:避免循环引用
如果上述方法仍未解决,检查服务端返回的数据中是否存在循环引用(比如Mongoose的_id与父文档的关联引用)。可以在Mongoose Schema中配置toJSON选项,移除不必要的内部字段:
const QuestionSchema = mongoose.Schema({ // ...你的字段定义 testcases: [TestCaseSchema], }, { toJSON: { transform: function(doc, ret) { // 移除Mongoose内部字段 delete ret.__v; // 如果不需要_id也可以移除 // delete ret._id; return ret; } } });
内容的提问来源于stack exchange,提问作者Shardul Pathak
相关产品推荐
相关产品推荐

