N06第 1 / 1 课时未开始内容版本 1.0.0 · 核验于 2026-10-26

路由基础综合实践

路由基础综合实践 · 阅读后完成下方实验与检查题,再用「标记完成」记录进度。

学习目标

路由基础到这就齐了,这课把它们拼成完整流程:课程从浏览到详情,面包屑指路、目录可跳、加载有反馈、失败有兜底、无效参数有归宿、随时能回去。读完你应该能交付一个「每条岔路都有路牌」的路由体系。

问题场景

前三课搭出的路由还缺很多东西:数据慢时白屏,组件报错时白屏,用户手动输错 URL 时框架默认 404,面包屑没有,从详情页回列表还得点浏览器后退。真实页面里这些路径每天都会发生,每条都要有设计好的出口。

核心解释

App Router 用约定文件给每条岔路配出口,它们都放在对应目录里、自动生效:

app/courses/
├── page.tsx                列表页
├── loading.tsx             列表慢时的即时占位(自动包裹 page)
├── error.tsx               列表渲染报错的兜底(客户端组件)
├── not-found.tsx           notFound() 触发时渲染
└── [slug]/
    ├── page.tsx            详情页
    ├── loading.tsx         详情慢时的骨架屏
    └── error.tsx           详情报错的兜底

三个关键机制:

loading.tsx 是 Suspense 的语法糖。同目录出现它,page 的异步渲染就被包进 Suspense,先发布局和骨架屏,数据好了再流式补上。慢的是哪段就给哪段配。

error.tsx 必须是客户端组件,接收 error 和 reset:

"use client";
export default function CourseError({
  error,
  reset,
}: {
  error: Error & { digest?: string };
  reset: () => void;
}) {
  return (
    <div>
      <p>课程加载失败:{error.message}</p>
      <button onClick={reset}>重试</button>
    </div>
  );
}

reset 尝试重新渲染出错的路由段。error 边界只兜自己目录以下的渲染错误,布局和导航不受影响(N03 验证过)。

面包屑从动态段取材。详情页里用已 await 的 params 拼:

<nav aria-label="面包屑">
  <Link href="/courses">课程</Link>
  <span> / </span>
  <span aria-current="page">{course.title}</span>
</nav>

返回导航优先用 Link 回到明确地址,而不是依赖浏览器历史——用户可能直接从书签进入详情页,历史里没有「上一页」。

示例拆解

完整流程的验证清单(每条都要真机走一遍):

  • 浏览:首页 → 课程列表 → 详情 → 面包屑「课程 / xxx」→ 点面包屑回列表;
  • 加载:给详情页数据获取加 1 秒延迟,导航后立即出现骨架屏(loading.tsx),数据到达后替换;
  • 失败:详情页里对某个特定 slug 抛错,看到本目录 error.tsx 兜底,导航完好,点「重试」换正常 slug 能恢复;
  • 无效参数:访问 /courses/不存在,notFound() 渲染 404 页,提供回列表链接;
  • 目录:列表页的筛选导航在所有兜底页面之外仍可用。

动手任务

在项目里完成三个小改动:

  1. 给 /courses 和 /courses/[slug] 各配 loading 和 error,详情页骨架屏做成标题条 + 两行占位。
  2. 详情页加面包屑导航,列表页加「筛选不变、只换页码」的返回链接。
  3. 制造三类故障(慢、错、不存在),把六条验证路径全部走一遍并记录现象。

常见错误

  • error.tsx 忘写 "use client":它本质上要管理错误状态和重试交互,服务端组件做不了,build 时会报错。
  • 把所有兜底都堆在根级:根级 error.tsx 是最后防线,子目录不配兜底的话,一个页面的报错会冒泡一大片;就近配置,错误影响面最小。
  • loading 放错了层级:放在 /courses/[slug]/loading.tsx 只在详情段生效;想让布局也即时出现,就把 loading 放在更外层。
  • 返回按钮用 history.back() 兜底一切:直达用户没有历史可回;明确目的地的返回一律用 Link 指向真实路由。

检查与复盘

完成下方检查题确认理解。自查清单:

  • 每个路由段都有 loading / error / not-found 三件套(按需),且层级放对了
  • 面包屑和返回链接都指向明确路由,不依赖历史记录
  • 慢、错、无效参数三条故障路径全部人工验证过

参考资料

检查题共 1 题,提交后立即显示解析
答案由服务端判定;答错的题会自动进入复习计划。
Q1单选简单

项目里有 app/(shop)/cart/page.tsx 和 app/(marketing)/about/page.tsx。对应的访问地址分别是?

读完这一课了?

标记完成后,工作台会安排接下来的学习。

Command Palette

Search for a command to run...