Next.js App Router 约定式文件实战:loading、error、not-found 怎么兜住加载态与异常

发布时间:2026/11/13 8:10:29

Next.js App Router 约定式文件实战:loading、error、not-found 怎么兜住加载态与异常 Next.js App Router 约定式文件实战:loading、error、not-found 怎么兜住加载态与异常用 Next.js App Router 写页面,你迟早会遇到这三个问题:页面里await fetch(...)拉数据时,用户盯着一片空白,不知道是在加载还是卡死了。接口挂了或抛异常,整个页面直接白屏崩掉,还可能把错误堆栈暴露给用户。用户访问了一个不存在的资源(比如/posts/99999),你想给个像样的 404 页,而不是默认那个丑页面。很多人第一反应是在组件里手写isLoading、try/catch、if (!data) return NotFound/。但 App Router 提供了约定式文件——在路由目录里放特定文件名,框架自动帮你接管加载态、错误态和 404。这篇把loading.tsx、error.tsx、not-found.tsx三个一次讲透。朴素写法:所有状态挤在一个组件里先看不用约定式文件时,一个详情页大概长这样:// app/posts/[id]/page.tsx —— 反面教材 use client; import { useEffect, useState } from react; export default function PostPage({ params }: { params: { id: string } }) { const [post, setPost] useState(null); const [loading, setLoading] useState(true); const [error, setError] useState(null); useEffect(() { fetch(/api/posts/${params.id}) .then(r { if (!r.ok) throw new Error(加载失败); return r.json(); }) .then(setPost) .catch(setError) .finally(() setLoading(false)); }, [params.id]); if (loading) return p加载中.../p; if (error) return p出错了/p; if (!post) return p找不到文章/p; return articleh1{post.title}/h1p{post.body}/p/article; }问题很明显:业务渲染只有最后一行,前面全是状态判断的噪音;而且被迫写成客户端组件(use client),丢掉了服务端组件直接await数据的能力。App Router 的约定式文件就是来拆掉这些样板的。loading.tsx:自动加载态,基于 Suspense在路由目录放一个loading.tsx,Next.js 会自动用它包一层 Suspense。当同级page.tsx(服务端组件)在await数据时,先渲染loading.tsx的内容,数据好了再换成真实页面:// app/posts/[id]/loading.tsx export default function Loading() { // 骨架屏,比加载中...体验好得多 return ( div classNameanimate-pulse space-y-4 div classNameh-8 w-2/3 bg-gray-200 rounded / div classNameh-4 w-full bg-gray-200 rounded / div classNameh-4 w-5/6 bg-gray-200 rounded / /div ); }有了它,page.tsx就能回归纯粹的服务端组件,直接await,不用管 loading:// app/posts/[id]/page.tsx —— 服务端组件,直接 await export default async function PostPage({ params, }: { params: Promise{ id: string }; }) { const { id } await params; // Next.js 15 起 params 是 Promise const res await fetch(https://api.example.com/posts/${id}); const post await res.json(); return ( article h1{post.title}/h1 p{post.body}/p /article ); }关键理解:loading.tsx的本质就是给page.tsx套了Suspense fallback{Loading/}。所以它对「路由跳转时的加载」和「组件 await 期间」都生效,你什么都不用手写。error.tsx:兜住渲染异常,必须是客户端组件如果page.tsx里的 fetch 抛了异常,或者渲染过程报错,同级的error.tsx会接住它,展示降级 UI,而不是整页白屏:// app/posts/[id]/error.tsx use client; // ← error.tsx 必须是客户端组件,这是硬性要求 import { useEffect } from react; export default function Error({ error, reset, }: { error: Error { digest?: string }; reset: () void; // 调它会重新渲染这段路由,相当于重试 }) { useEffect(() { // 上报到监控系统,别把错误吞了 console.error(页面渲染出错:, error); }, [error]); return ( div classNamep-6 text-center h2 出了点问题/h2 p classNametext-gray-500{error.message}/p button onClick{() reset()} classNamemt-4 px-4 py-2 bg-blue-600 text-white rounded 重试 /button /div ); }有两个坑要记牢:坑一:error.tsx必须加use client。它内部用 React 错误边界实现,错误边界只能是客户端组件。忘了加,构建直接报错。坑二:error.tsx抓不到同级layout.tsx的错误。因为 error 边界包在 layout 内部,layout 本身抛错它管不着。要兜住 layout 的错误,得在上一级目录放error.tsx,或者用global-error.tsx兜住根 layout。reset()函数是 App Router 特有的:调用它会尝试重新渲染出错的这段路由子树,给用户一个「重试」而不用刷新整页。not-found.tsx notFound():优雅的 404资源不存在时,别手动return div404/div。App Router 提供了notFound()函数,调用它会立即中断渲染,并渲染最近的not-found.tsx:// app/posts/[id]/page.tsx import { notFound } from next/navigation; export default async function PostPage({ params, }: { params: Promise{ id: string }; }) { const { id } await params; const res await fetch(https://api.example.com/posts/${id}); if (res.status 404) { notFound(); // ← 中断渲染,跳到 not-found.tsx,后面代码不会执行 } const post await res.json(); return articleh1{post.title}/h1p{post.body}/p/article; }// app/posts/[id]/not-found.tsx import Link from next/link; export default function NotFound() { return ( div classNamep-6 text-center h2文章不存在/h2 p classNametext-gray-500你要找的文章可能已被删除。/p Link href/posts classNametext-blue-600 underline 返回文章列表 /Link /div ); }notFound()的原理是抛出一个特殊错误,被框架捕获后渲染not-found.tsx,同时响应状态码正确返回 404——这点对 SEO 很重要,搜索引擎知道这是不存在的页面,不会收录。手写div404/div的话状态码还是 200,搜索引擎会以为是正常页。它们的嵌套关系:一张图理清这几个约定式文件不是平级的,它们的包裹顺序是固定的。同一个路由段里,Next.js 大致这样嵌套:layout error ← 兜住下面的渲染错误 suspense fallback{loading} ← loading 兜住加载态 not-found 边界 page ← 你的实际页面 /not-found /suspense /error /layout从这张图能推出几条实用结论:loading和error都定义在路由段上,子路由可以有自己的一套,就近生效。error在layout内层,所以管不到同级 layout 的错误(要放上一级)。not-found既能被notFound()主动触发,也会兜住未匹配的路由。小结App Router 的三个约定式文件,把过去挤在组件里的状态处理拆成了框架职责:loading.tsx:自动 Suspense fallback,让page.tsx回归纯服务端组件直接await,写骨架屏体验最佳。error.tsx:错误边界,必须use client;提供reset()做重试;抓不到同级 layout 的错误,要放上一级。not-found.tsxnotFound():优雅 404,且返回正确的 404 状态码,对 SEO 友好;notFound()会中断后续渲染。记忆点:别再手写isLoading / try-catch / 404 判断——在路由目录里放对文件名,框架自动帮你套好 Suspense 和错误边界。
延伸阅读

更多相关文章

2026/11/13 8:07:30

电工证要什么学历怎么报名多少钱全知道

电工证要什么学历怎么报名多少钱全知道 你是不是也觉得学历不高就报不了电工证?别急,我来给你说说真实情况,包括报名流程、费用以及你最关心的学历门槛,别让学历拦住了你的路。 一、电工证要什么学历才能报考?…

2026/11/13 8:07:30

三个电工证用途到期换证流程网上查询全攻略

三个电工证用途到期换证流程网上查询全攻略 之前考的证在外省能不能转过来?这是很多电工朋友在换证或复审时最关心的问题,尤其是像你这种在开封从事房建工程的朋友,经常需要跨省作业,证书的流动性和认可度就显得特别重要。通过【网上查询】平台,你可以轻…

2026/11/13 8:07:30

中江电工证怎么考 你知道郑州报考避坑指南吗

中江电工证怎么考 你知道郑州报考避坑指南吗 之前考的证在外省能不能转过来?这个问题几乎是每个打算报考或正在准备转证的电工朋友心中的头等大事。特别是像南阳这样的地方,水利工程从业者越来越多,电工证不仅关系到日常工作,还直接影响到能否参与项目投…

2026/11/12 20:35:13

电工证丢失还能补吗?千万别踩坑,丢了证等于失业

电工证丢失还能补吗?千万别踩坑,丢了证等于失业 你正在找工作,但手里的电工证突然丢了,这下怎么办?别急,先别慌, 电工证丢失还能补吗 ?答案是肯定的,但 千万别踩坑 ,补办流程如果不了解,可能会耽误你上岗、甚至影响到你的收入。…

2026/11/13 0:01:06

办上海高压电工证良心建议:别被中介坑了,自己看这篇就够了

办上海高压电工证良心建议:别被中介坑了,自己看这篇就够了 你是不是也像我一样,第一次听说“高压电工证”这个名词,就感觉一头雾水?其实很多人都跟我一样,不知道去哪报名、怕被中介坑,结果花了冤枉钱还考不上。今天我就从一个在商丘培训过的学员角度,…

2026/11/13 0:01:06

黎里考电工证在哪里值不值得考

黎里考电工证在哪里值不值得考 之前考的证在外省能不能转过来?这是很多在外地工作、准备回老家发展的朋友最关心的问题。特别是在黎里地区,很多从事电力相关工作的朋友,都面临这样一个难题: 外省的电工证能否在本地使用?值不值得考?…

2026/11/13 0:01:06

毕节哪里考电工证 怎么报名学历不高也能上手

毕节哪里考电工证 怎么报名学历不高也能上手 你是不是也和我一样,学历不高,想着考个电工证,但又担心自己条件不够,怕报不上名?其实不然,只要符合条件,学历不高也能考电工证。今天就来聊聊【毕节哪里考电工证】这个问题,还有怎么报名,让你一步到位不…

2026/11/12 22:10:13

面向复杂光照与角度的宠物面部识别鲁棒性增强策略

在智慧养宠时代,基于视觉的宠物身份识别技术正逐步从实验室走向家庭应用。然而,与配合度高的人类不同,宠物是典型的“非合作生物识别对象”——它们不会主动配合摄像头调整姿态,更无法控制光照环境。实际应用中,我们常…

2026/11/12 9:51:42

SSM电子书店源码全解析:结构、原理、部署与排错实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑