为什么在生产环境部署的 Next.js 首次加载时 useSession() 为未定义(以及我如何修复的)

发布: (2026年1月15日 GMT+8 05:03)
3 min read
原文: Dev.to

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

Back to Blog

相关文章

阅读更多 »