Next.js:把页面、路由和服务端代码放进同一项目
Next.js 在 React 组件之上提供路由、服务端执行和构建约定。先判断代码需要浏览器能力还是可以留在服务端。
- 建立任务首页和详情页,直接访问、内部跳转与刷新都正常,并能说明组件在哪一端运行。
- 文件系统路由、布局与页面边界
- 演练Next.js:把页面、路由和服务端代码放进同一项目后,应当建立任务首页和详情页,直接访问、内部跳转与刷新都正常,并能说明组件在哪一端运行,并保留类型检查、生产构建、浏览器行为和请求结果作为可重复检查的依据。
- 完成 4.5「数据、状态与 URL 驱动界面」
FOUNDATION
必须理解
Next.js 是 React 框架,提供路由、服务端渲染、数据获取、接口和生产构建约定。它让页面组件进入完整应用结构,但也要求理解哪些代码运行在服务器、哪些运行在浏览器。
本课依次讲清文件系统路由、布局与页面边界、服务端组件与客户端组件和预渲染、动态渲染、元数据与首屏体验,最后通过“为三类页面设置标题,测试直接访问、刷新和不存在 ID”检查学习结果。
React 像房间内的家具系统,Next.js 像包含楼层、走廊、门牌、前台和设备间的整栋建筑规则。
任务应用的 app/page.tsx 是首页,app/tasks/[id]/page.tsx 是详情页,布局提供导航;数据读取默认在服务器,交互表单才进入客户端。
文件系统路由、布局与页面边界
在 App Router 里,文件夹和 page.tsx 会直接组成 URL,layout.tsx 可以包住一组页面。写成 [id] 的动态文件夹,则会把地址里的那一段交给页面使用。
基础概念
Next.js App Router 使用文件系统约定定义页面:`page.tsx` 提供路由内容,`layout.tsx` 包住一组页面,方括号目录表示从 URL 读取的动态片段。
进一步理解
路由段与目录对应,布局可以嵌套并在子页面切换时保留公共结构。`loading`、`error`、`not-found` 等约定文件负责相应边界状态。
动态路由 `[id]` 只说明地址形状,不证明 id 有效。页面仍需查询数据,并在不存在或无权限时返回正确结果。
`app/tasks/[id]/page.tsx` 接收地址 `/tasks/42` 中的 id,再读取任务 42;公共导航放在上层 layout。
文件系统路由不是把文件内容直接公开,访问者不能任意读取源码;框架根据约定执行组件并生成响应。
这一小节记住:目录定义地址结构,页面处理当前段,布局承载共享界面。
服务端组件与客户端组件
服务端组件先在服务器上生成结果,适合读数据和输出内容;需要点击事件、状态或浏览器 API 的部分才加 use client。客户端边界越小,页面通常越轻。
基础概念
App Router 中页面和布局默认是服务端组件;需要状态、事件处理或浏览器专用 API 时,才在客户端边界入口使用 `use client`。
进一步理解
服务端组件可在可信环境读取数据和秘密,并减少发送给浏览器的 JavaScript。客户端组件负责点击、输入、localStorage 等交互。
`use client` 会建立模块边界,该文件导入的客户端代码进入浏览器依赖图。服务端可把可序列化数据传给客户端,但秘密不能作为 props 送出。
任务详情在服务端读取记录并输出标题,只有切换完成状态的按钮是小型客户端组件,通过事件提交变化。
客户端组件也可能参与服务端预渲染,它不是“只在浏览器生成”;关键区别是其代码和交互能力会进入客户端。
这一小节记住:默认把读取与静态展示留在服务端,把客户端边界缩到确实交互处。
预渲染、动态渲染、元数据与首屏体验
有些页面可以提前生成,有些必须等用户请求时再读数据。metadata 管浏览器标题和分享信息,页面里的 h1 仍然要自己写,二者解决的不是一件事。
基础概念
预渲染是在用户请求前或请求过程中生成可发送的 HTML;静态内容可提前准备,动态内容需根据请求、身份或实时数据决定。元数据描述页面给浏览器、搜索和分享平台的信息。
进一步理解
构建时生成适合公开且变化少的内容,请求时渲染适合个性化与实时数据。缓存会改变再次访问的计算时机,因此必须理解数据新鲜度。
title 与 description 帮助识别页面,但不能代替正文的 h1、语义结构和真实内容。首屏体验还受数据等待、流式响应与客户端脚本大小影响。
公开课程页可预生成;用户自己的任务页必须按身份读取。两者都设置准确标题,并为加载过程提供可理解反馈。
动态不等于一定更慢,静态也不等于永远正确;选择取决于数据是否依赖请求以及允许多旧。
这一小节记住:按数据时效和身份需求选择渲染时机,再用元数据准确描述页面。
- 文件位于 `app/tasks/[id]/page.tsx`。
- 当前 Next.js 版本的 params 是异步值,因此页面函数使用 async。
export default async function TaskPage({
params,
}: { params: Promise<{ id: string }> }) {
const { id } = await params;
return <h1>任务 {id}</h1>;
}阅读Next.js:把页面、路由和服务端代码放进同一项目示例时,位于 app/tasks/[id]/page.tsx 时,URL 中的 id 会通过 params 交给页面。
- 类型说明 params 最终提供字符串 id。
- await params 取得当前动态路由片段,而不是从浏览器全局对象读取。
- 示例只展示参数;真实页面还要查询资源并处理不存在与无权限。
访问 `/tasks/42` 时页面显示“任务 42”;换成其他地址片段会显示对应值,未知 id 的业务校验仍需另行实现。
AI COLLABORATION
AI 如何参与
在Next.js:把页面、路由和服务端代码放进同一项目这一课,AI 负责根据真实材料解释文件系统路由、布局与页面边界并指出遗漏,学习者负责控制范围、执行修改和核对类型检查、生产构建、浏览器行为和请求结果。
推荐协作顺序
- 1
先让 AI 根据 URL 需求画出 app 目录,不生成页面细节。
- 2
逐个组件询问它是否真的需要事件、状态或浏览器 API。
- 3
把客户端边界压到最小后,再验证直接访问、刷新和 404。
这是 Next.js 文件树和组件代码。请按文件说明路由作用、运行位置和数据来源。只有确实需要事件或浏览器 API 时才建议 use client,并给直接访问与刷新的验收步骤。
路由与文件结构一一对应,大部分页面保持服务端,只有表单和交互控件作为小型客户端组件;Next.js:把页面、路由和服务端代码放进同一项目的人工验收必须回到真实页面、请求、终端、测试或数据结果,不能用 AI 的文字说明代替。
人工检查清单
- 确认动态参数正确读取,内部导航使用 Link,刷新详情页仍能工作,metadata 不含虚构数据。
- 要求 AI 为每个组件说明必须在哪个环境运行的具体理由,并指出传输边界。
- 直接访问、刷新动态路由并检查页面源码与交互,验证路由和渲染时机符合预期。
COMMON TRAPS
常见误区
下面三类问题会让任务看似完成,却经不起刷新、错误输入或真实环境检查。先看现象,再找原因和修正方法。
所有文件都加 use client
- 你会看到
- 浏览器脚本增多,服务端能力被放弃
- 为什么发生
- 客户端边界会把相关模块送进浏览器,也放弃只在服务端运行的机会。
- 怎样纠正
- 把交互限制在最小组件边界
只测试内部跳转
- 你会看到
- 刷新详情地址后出现 404 或数据缺失
- 为什么发生
- 客户端跳转可能复用已有数据,直接访问才会暴露路由和首次加载问题。
- 怎样纠正
- 每个公开路由都做直接访问测试
在两端混用秘密
- 你会看到
- 服务端环境变量被带入浏览器代码
- 为什么发生
- 浏览器代码会交付给访问者,进入客户端包的值不能再视为秘密。
- 怎样纠正
- 明确变量使用位置与公开前缀
HANDS-ON
动手任务
建立任务首页和详情页,直接访问、内部跳转与刷新都正常,并能说明组件在哪一端运行。
- 完成 4.5「数据、状态与 URL 驱动界面」
跟着做
- 01
创建首页、关于页和共享布局。
- 02
加入任务详情动态路由并使用示例参数。
- 03
使用 Link 在页面之间导航。
- 04
把 TaskForm 单独标记为客户端组件。
- 05
为三类页面设置标题,测试直接访问、刷新和不存在 ID。
建立任务首页和详情页,直接访问、内部跳转与刷新都正常,并能说明组件在哪一端运行。
为不存在的任务返回专用 404,并为详情页生成包含任务标题的 metadata。
离开本课前,自问四件事
- page、layout、动态路由段分别怎样组成 URL 与页面?
- 哪些能力必须使用客户端组件,哪些适合留在服务端?
- use client 为什么应放在尽量小而明确的边界?
- 静态与动态渲染应根据哪些数据条件选择?
确认完成后,会同步更新学习中心的课程学习进度。