Next.js服务端组件传props到客户端组件时出现栈溢出错误
问题:传递Props给客户端组件时触发栈溢出错误
从数据库获取数据后通过客户端组件渲染(后续计划添加useState),但只要给客户端组件传递props就触发Maximum call stack exceeded错误,不传则正常运行。
服务端组件代码
'use server' import { Exam } from '@/db/models/exam'; import { ExamPaper } from './client-exam-paper'; const ExamPage = async ({ params }) => { const exam = await Exam.findById(params.examId); // client component return <ExamPaper exam={exam} />; // error return <ExamPaper />; // okay }; export default ExamPage;
客户端组件代码
'use client'; export function ExamPaper() { return <div>asdfghjk</div>; }
错误信息
Error: Maximum call stack exceeded
原因分析
你遇到的栈溢出是因为Mongoose返回的exam是文档对象实例,不是普通JavaScript对象。当Next.js尝试序列化这个对象传递给客户端组件时,会递归遍历对象的所有属性,包括Mongoose内部的原型链、方法和隐藏字段,导致无限递归调用,最终触发栈溢出。
解决方法
把Mongoose文档转换为普通JS对象后再传递:
方案1:使用toObject()转换整个文档
修改服务端组件代码,将exam转成普通对象:
'use server' import { Exam } from '@/db/models/exam'; import { ExamPaper } from './client-exam-paper'; const ExamPage = async ({ params }) => { const exam = await Exam.findById(params.examId); // 转换为普通JS对象 return <ExamPaper exam={exam.toObject()} />; }; export default ExamPage;
方案2:只传递需要的字段(更高效)
如果不需要整个文档的所有字段,可以在查询时指定返回的字段,再转换为普通对象:
'use server' import { Exam } from '@/db/models/exam'; import { ExamPaper } from './client-exam-paper'; const ExamPage = async ({ params }) => { // 只查询需要的字段,减少数据量 const exam = await Exam.findById(params.examId).select('title description questions'); return <ExamPaper exam={exam.toObject()} />; }; export default ExamPage;
内容的提问来源于stack exchange,提问作者Xenon M. Bird
相关产品推荐
相关产品推荐

