Next.js 13.4 @folder/loading.js无法正常工作问题求助
Next.js 13.4 App Router:插槽内容不触发loading状态的解决方案
问题分析
核心矛盾在于客户端组件布局阻断了插槽内页面的loading逻辑触发:
app/platform/layout.tsx标记为"use client"组件,在useSession处于loading状态时,直接用<div>LOADING CLIENT</div>替换了main和widgets插槽内容——导致插槽内的页面组件(及其绑定的loading.js)完全没被渲染,自然无法触发页面级加载状态。- App Router的
loading.js仅在页面/子组件执行异步数据请求时才会触发显示,而你的布局逻辑在session加载阶段直接中断了页面组件的渲染流程。
解决方案
1. 拆分客户端认证逻辑,恢复布局的服务器组件特性
把客户端的session认证逻辑封装到独立组件中,让布局本身作为服务器组件,避免阻塞插槽渲染:
步骤1:创建客户端认证守卫组件
新建app/components/ClientAuthGuard.tsx:
"use client"; import { useSession } from "next-auth/react"; import { redirect } from "next/navigation"; export default function ClientAuthGuard({ children }: { children: React.ReactNode }) { const { status } = useSession(); if (status === "loading") { return <div>LOADING CLIENT</div>; } if (status === "unauthenticated") { redirect("/auth"); } return <>{children}</>; }
步骤2:修改Platform布局为服务器组件
更新app/platform/layout.tsx,移除"use client",用认证守卫包裹插槽内容:
import { CactusLayout, CactusSection } from "medzy/components/layouts/Cactus"; import ClientAuthGuard from "../components/ClientAuthGuard"; export default function LayoutPlatform({ main, widgets }: { main: React.ReactNode; widgets: React.ReactNode; }) { return ( <CactusLayout> <CactusSection specify="w-1/12 xl:w-1/4" right border> <div>SIDEBAR</div> </CactusSection> <ClientAuthGuard> <CactusSection specify="flex-1">{main}</CactusSection> {widgets} </ClientAuthGuard> </CactusLayout> ); }
2. 正确配置页面级loading.js
确保loading.js放在app/platform/目录下,且页面组件包含异步逻辑:
创建app/platform/loading.js
export default function Loading() { return <div>页面加载中...</div>; }
给页面组件添加异步触发逻辑
修改app/platform/page.tsx:
export default async function PlatformPage() { // 模拟异步数据请求,触发loading.js显示 await new Promise(resolve => setTimeout(resolve, 2000)); return <div>Platform页面内容</div>; }
3. 关键注意事项
- 确认
next-auth的路由配置(app/api/auth/[...nextauth]/route.ts)正确,session策略设置合理(如jwt)。 loading.js仅在页面存在async/await异步操作时才会触发,无异步逻辑则不会显示。- 避免在布局组件中直接替换插槽内容,通过嵌套组件处理认证状态,保证页面组件正常参与渲染流程。
内容的提问来源于stack exchange,提问作者DJIDA ISSAM
相关产品推荐
相关产品推荐

