Next.js传递API响应Props给子组件时触发RangeError求助
我是Next.js新手,尝试将API调用返回的响应作为Props传递给子组件时,出现了RangeError: Maximum call stack size exceeded错误。静态传递数据时功能正常,但传递动态渲染的API响应数据时就会报错。
错误截图

相关代码
page.jsx
import styles from './page.module.css'; import EmployeeDashboardNavbar from './serverComponents/EmployeeNavbar'; import EmployeeDashboardContent from './serverComponents/employeeDashboardContent'; const EmployeeDashboard = () => { return ( <div className={styles["emp-dashboard-top"]}> <div className={styles["emp-dashboard-body"]}> <EmployeeDashboardNavbar /> <EmployeeDashboardContent /> </div> </div> ); }; export default EmployeeDashboard;
EmployeeDashboardContent.jsx
import { findTaskswithDeptAdmin } from "@/actions/taskActions"; import EmpCards from "../clientComponents/employeeCard"; import styles from "./server.module.css"; import EmployeeCalendar from "../clientComponents/calendar"; const EmployeeDashboardContent = async () => { const tasksOfUser = await findTaskswithDeptAdmin({ empId: "652a39fbfd78c72ec09f26b5", }); const filteredTasks = tasksOfUser.filter((tk) => tk.completionStatus === "Assigned") console.log(filteredTasks); return ( <> <div className={styles["emp-dash-main"]}> <div style={{ width: "100%", display: "flex" }}> <div className={styles["emp-dash-main-left"]}> <div> <div> <div className={styles["emp-header-nav"]}> <div className={styles["emp-header"]}> <h3>Krish</h3> </div> </div> <EmpCards /> </div> <div className={styles["emp-body"]}> <div className={styles["emp-meeting-schedule"]}> <button className={styles["emp-dashboard-add-employee"]}> Meeting Details </button> </div> <div> <table className={styles["emp-dash"]}> <thead> <tr className={styles["emp-table-head"]}> <th>Task</th> <th>Head</th> <th>Department</th> <th>Date</th> </tr> </thead> <tbody> {tasksOfUser .filter((tk) => tk.completionStatus === "Assigned") .map((task) => ( <tr className={styles["emp-dashboard-table-data"]} key={task._id} > <td>{task.taskName}</td> <td>{task.deptId.name}</td> <td>{task.adminId.adminName}</td> <td>{task.deadline}</td> </tr> ))} </tbody> </table> </div> <EmployeeCalendar tasks={filteredTasks}/> </div> </div> </div> <div className={styles["emp-dash-main-right"]}>hiii</div> </div> </div> </> ); }; export default EmployeeDashboardContent;
EmployeeCalendar.jsx
"use client"; import Calendar from "react-calendar"; import 'react-calendar/dist/Calendar.css'; import styles from "./client.module.css"; const EmployeeCalendar = ({tasks}) => { console.log(tasks) return ( <> <div className={`${styles["emp-calender"]} ${styles["react-calender"]}`} style={{ display: "grid", placeItems: "center" }} > {/* <div> <h4 style={{ cursor: "pointer", color: "red" }}>Today</h4> </div> */} <Calendar /> </div> </> ); }; export default EmployeeCalendar;
filteredTasks数据示例
[ { taskName: 'task 3', adminId: { adminName: 'Krish', email: 'krish@gmail.com', password: '123', document: 'PAN', __v: 0 }, deptId: { name: 'HR', __v: 0 }, deadline: '2023-10-21', status: false, completedDate: '', completionStatus: 'Assigned', createdAt: '2023-10-23T12:27:33.523Z', updatedAt: '2023-10-23T12:27:33.523Z', __v: 0 } ]
静态传递数据时可以正常运行,但不明白为什么动态渲染的API响应数据传递时会出错。
问题原因与解决方案
这个错误的核心原因是Next.js在序列化服务器组件传递给客户端组件的Props时,遇到了无法处理的循环引用或非可序列化数据。API返回的filteredTasks里包含MongoDB文档对象(比如带__v字段的嵌套对象),这类对象可能隐含循环引用,或者包含无法被JSON序列化的属性,导致序列化过程陷入无限循环,最终触发栈溢出。
具体修复步骤:
序列化API响应数据:在服务器组件中,将API返回的任务数据转换为纯JSON对象,去除MongoDB文档的额外属性和潜在循环引用。
修改EmployeeDashboardContent.jsx中的数据处理逻辑:const tasksOfUser = await findTaskswithDeptAdmin({ empId: "652a39fbfd78c72ec09f26b5", }); // 将MongoDB文档转为纯JSON对象 const serializedTasks = JSON.parse(JSON.stringify(tasksOfUser)); const filteredTasks = serializedTasks.filter((tk) => tk.completionStatus === "Assigned");这样处理后,数据会变成纯可序列化的JSON结构,消除循环引用和非标准属性。
仅传递必要数据:如果不需要所有字段,可以手动提取需要的属性,减少传递的数据量同时避免不必要的嵌套问题。比如:
const filteredTasks = tasksOfUser .filter((tk) => tk.completionStatus === "Assigned") .map(task => ({ taskName: task.taskName, deadline: task.deadline, // 只传递日历组件需要的字段 }));检查组件Props处理:后续若要在日历组件中使用
tasks,确保组件不会因复杂数据结构触发额外的渲染循环。
验证逻辑
静态数据能正常运行,是因为静态数据本身就是纯JSON结构,没有MongoDB文档的额外属性和潜在循环引用,序列化过程不会出问题。而动态API返回的是MongoDB文档实例,必须先转为纯JSON才能安全传递给客户端组件。
内容的提问来源于stack exchange,提问作者Krish

