Next.js报错:React Context在Server Components中不可用,求修复
错误原因
你的ChatbotIdPage是服务端组件(async/await组件在Next.js App Router中默认是服务端组件),而useSession是NextAuth的客户端钩子,依赖React Context运行。服务端组件不支持React Context,因此直接调用会触发该错误。
推荐修复方案:服务端获取会话(更安全高效)
改用NextAuth的getServerSession在服务端获取用户会话,无需依赖React Context,同时保持组件为服务端组件,可直接执行数据库查询:
import { getServerSession } from "next-auth/next"; import { authOptions } from "@/lib/auth"; // 替换为你的NextAuth配置文件路径 import prisma from "@/lib/prisma"; import { ChatbotClient } from "./components/chatbot-client"; import { redirect } from "next/navigation"; interface ChatbotIdPageProps { params: { chatbotId: string; }; } const ChatbotIdPage = async ({ params }: ChatbotIdPageProps) => { // 在服务端安全获取用户会话 const session = await getServerSession(authOptions); if (!session?.user) { redirect("/demo"); } // 直接使用session.user.id(假设你的用户模型包含id字段),无需JSON序列化 const userId = session.user.id; // 查询当前用户拥有的指定聊天机器人 const chatbot = await prisma.chatbot.findUnique({ where: { id: params.chatbotId, userId: userId, }, }); // 如果聊天机器人不存在或不属于当前用户,重定向到演示页 if (!chatbot) { redirect("/demo"); } return <ChatbotClient initialData={chatbot} />; }; export default ChatbotIdPage;
关键说明
getServerSession直接在服务端验证会话,避免客户端暴露敏感信息- 保持组件为服务端组件,可直接执行Prisma查询,无需额外API路由
- 修复了原代码中
JSON.stringify(session.user)的错误——Prisma查询的userId应该是用户ID字符串,而非JSON序列化后的用户对象
备选方案:转为客户端组件(适用于需客户端交互场景)
如果你的组件需要客户端交互逻辑,可标记为客户端组件,并将数据库查询移至API路由:
1. 修改页面组件为客户端组件
'use client'; import { useSession } from "next-auth/react"; import { ChatbotClient } from "./components/chatbot-client"; import { redirect } from "next/navigation"; import { useEffect, useState } from "react"; interface ChatbotIdPageProps { params: { chatbotId: string; }; } const ChatbotIdPage = ({ params }: ChatbotIdPageProps) => { const { data: session } = useSession(); const [chatbot, setChatbot] = useState(null); useEffect(() => { if (!session?.user) { redirect("/demo"); } // 从API路由获取聊天机器人数据 const fetchChatbot = async () => { const res = await fetch(`/api/chatbots/${params.chatbotId}`); if (!res.ok) { redirect("/demo"); } const data = await res.json(); setChatbot(data); }; fetchChatbot(); }, [session, params.chatbotId]); if (!session?.user) return null; if (!chatbot) return <div>Loading...</div>; return <ChatbotClient initialData={chatbot} />; }; export default ChatbotIdPage;
2. 创建对应的API路由(app/api/chatbots/[chatbotId]/route.ts)
import { getServerSession } from "next-auth/next"; import { authOptions } from "@/lib/auth"; import prisma from "@/lib/prisma"; import { NextResponse } from "next/server"; export async function GET(request: Request, { params }: { params: { chatbotId: string } }) { const session = await getServerSession(authOptions); if (!session?.user) { return NextResponse.json({ error: "Unauthorized" }, { status: 401 }); } const chatbot = await prisma.chatbot.findUnique({ where: { id: params.chatbotId, userId: session.user.id, }, }); if (!chatbot) { return NextResponse.json({ error: "Not found" }, { status: 404 }); } return NextResponse.json(chatbot); }
内容的提问来源于stack exchange,提问作者Victor Timi
相关产品推荐
相关产品推荐

