为什么在生产环境部署的 Next.js 首次加载时 useSession() 为未定义(以及我如何修复的)
Source: Dev.to
问题
当我将 SaaS(Next.js 应用)部署到生产环境时,首次页面加载时 session 被记录为 undefined。刷新后(例如访问 /dashboard),会正确出现会话信息:
{ user: { … }, expires: "…" }
在本地环境从未出现过——只在生产环境出现。问题似乎与认证令牌有关,但令牌本身是正常的。
为什么会出现
useSession() 是异步的。首次渲染时,React 会立即挂载组件,而 useSession() 在后台开始获取会话。在第一次渲染期间会话数据尚未就绪,因此 console.log(session) 打印出 undefined,且钩子的 status 为 "loading"。
在本地环境,应用运行较慢,给会话请求留出了更多的解析时间,你不太会注意到这条日志。而在生产环境,应用加载更快,渲染在会话准备好之前就已经发生,从而暴露出 undefined 的值。
解决办法
在客户端检查会话状态
import { useSession } from "next-auth/react";
const Component = () => {
const { data: session, status } = useSession();
if (status === "loading") {
return null; // 或者返回一个加载中的 spinner
}
if (!session) {
redirect("/login");
}
// 渲染受保护的内容
};
在会话存在之前延迟 useEffect
import { useEffect } from "react";
useEffect(() => {
if (!session) return; // 等待会话就绪
fetchBills(session.user.id);
}, [session]);
收获
- 渲染会在异步数据(如
useSession)准备好之前发生,因此必须处理初始的undefined状态。 - 这一模式适用于任何异步数据来源:API 调用、数据库查询、React Query 等。
- 仅在生产环境出现的 bug 往往源于时序差异,而不是逻辑错误本身。
感谢阅读。如果对你有帮助,欢迎分享或与我联系。
Athashri Keny