求助:Next.js项目出现Maximum call stack size exceeded错误
可能的问题点分析
1. Session变化引发的无限渲染循环
你的组件中formData的初始值直接依赖session.data?.user,但useSession是会随登录状态变化更新的Hook。当session异步加载完成(从loading转为authenticated)时,组件会重新渲染,但useState的初始值仅在第一次渲染时生效,后续渲染不会自动同步session更新到formData。如果session存在反复更新的情况(比如signIn触发session更新后,组件又依赖session执行操作),可能触发无限渲染循环。
修复方案:用useEffect监听session变化,同步更新formData:
import { useEffect } from "react"; // 在Config组件内添加 useEffect(() => { if (session.data?.user) { setFormData({ username: session.data.user.name as string, email: session.data.user.email as string, password: session.data.user.password as string, }); } }, [session]);
2. signIn调用的参数与跳转逻辑问题
在handleSubmitUser中,signIn的参数传递不符合Next Auth规范,且若callbackUrl指向的/admin页面包含当前Config组件,可能触发页面反复跳转、session反复更新,最终导致栈溢出。
Next Auth的signIn函数中,认证参数应合并到第二个options对象中,而非单独作为第三个参数,修改后:
signIn("credentials", { callbackUrl: "/admin", email: formData.email, password: formData.password });
同时确认/admin页面不会再次触发登录校验或session循环更新逻辑。
3. 表单reset按钮的意外影响
EditButton和CloseButton使用了type="reset",点击会触发表单重置事件,但你的表单是受控组件(值绑定到formData),重置操作不会同步更新formData状态,可能导致表单显示值与状态不一致,引发意外重渲染循环。
建议将按钮type改为button:
// EditButton和CloseButton组件中 <button type="button" // 替换原有的reset类型 onClick={onClick} className="bg-trendy-pink-600 p-1 my-2 mx-2 rounded-xl shadow-xl" >
4. PutUserConfig函数的内部逻辑检查
虽然你未提供PutUserConfig的代码,但如果该函数内部存在无限递归调用(比如无终止条件的递归、未限制次数的API重试循环),会直接导致栈溢出。请检查:
- 是否存在无终止条件的递归逻辑
- API请求失败时是否有无限重试的逻辑
- 是否存在循环调用自身或其他函数的情况
调试建议
- 用浏览器开发者工具的Performance面板录制渲染过程,排查是否存在无限重复的渲染任务
- 在
useEffect、handleSubmitUser等关键函数中添加console.log,跟踪调用次数,定位循环源头 - 临时注释
signIn调用,测试是否仍出现栈溢出,确认是否为登录逻辑导致的问题
内容的提问来源于stack exchange,提问作者Gustavo Hz

