Next.js 13中useSession刷新页面时无法获取会话信息求助
Next.js 13 订单页刷新/直接访问无限加载问题解决
问题场景
使用Next.js 13搭建电商克隆项目,订单页面通过next-auth/react的useSession判断用户登录状态:
- 通过站内链接导航进入订单页时,页面正常显示
- 刷新订单页或直接输入URL访问时,页面陷入无限加载状态
相关代码片段
订单页面代码
"use client"; // ... 其他导入代码 const Orders = async () => { const { data: session } = useSession(); // ... 页面逻辑代码 };
根布局页面代码
export default async function RootLayout({ children, }: { children: React.ReactNode; }) { return ( <html lang="en"> <body> <AuthProvider> <BasketProvider>{children}</BasketProvider> </AuthProvider> </body> </html> ); }
AuthProvider代码
"use client"; import { SessionProvider } from "next-auth/react"; const AuthProvider = ({ children }: { children: React.ReactNode }) => { return <SessionProvider>{children}</SessionProvider>; }; export default AuthProvider;
问题截图
问题原因
核心问题在于标记了"use client"的订单组件被定义为异步函数:
Next.js 13 App Router规则中,客户端组件(带"use client"指令)不能是异步函数,异步组件仅支持服务器组件。当刷新或直接访问时,客户端组件的async标识会导致React渲染流程异常,触发无限加载。
解决方案
1. 移除客户端组件的async标识
将订单组件从异步函数改为普通同步函数:
"use client"; // ... 其他导入代码 const Orders = () => { // 移除async关键字 const { data: session } = useSession(); // ... 页面逻辑代码 }; export default Orders;
2. 客户端组件内异步逻辑处理(如需)
如果需要在订单组件内执行异步操作(比如获取订单数据),使用useEffect结合状态管理实现:
"use client"; import { useState, useEffect } from 'react'; import { useSession } from "next-auth/react"; const Orders = () => { const { data: session } = useSession(); const [orders, setOrders] = useState([]); const [isLoading, setIsLoading] = useState(true); useEffect(() => { const fetchOrders = async () => { // 未登录时直接终止请求 if (!session?.user) { setIsLoading(false); return; } // 异步获取订单数据 try { const res = await fetch(`/api/orders?userId=${session.user.id}`); const data = await res.json(); setOrders(data); } catch (err) { console.error('获取订单失败:', err); } finally { setIsLoading(false); } }; fetchOrders(); }, [session]); // 依赖session变化重新执行 // 加载状态提示 if (isLoading) return <div>加载中...</div>; // 未登录提示或跳转 if (!session) return <div>请登录后查看订单</div>; // 渲染订单列表 return ( <div className="orders-container"> {orders.map(order => ( <div key={order.id} className="order-card"> {/* 订单内容 */} </div> ))} </div> ); }; export default Orders;
额外验证
根布局中用服务器组件包裹客户端AuthProvider的写法是合规的,无需修改——Next.js允许服务器组件嵌套客户端组件,保证SessionProvider能全局覆盖所有页面即可。
内容的提问来源于stack exchange,提问作者Murat Turhan
相关产品推荐
相关产品推荐

