返回博客列表

博客详情

Next.js App Router:路由、渲染与数据获取入门

从 pages 迁移视角理解 App Router 的核心概念

约 4 分钟阅读

Next.jsApp RouterReact

当你从 pages 目录迁移到 app 目录时,最先需要调整的不是语法细节,而是心智模型:路由如何由文件夹表达、布局如何嵌套、数据默认在哪里取。本文从工程视角整理 App Router 的常见决策点,便于在真实项目里落地。

为什么会出现 App Router

pages 路由以文件名为 URL,能力成熟,但在嵌套布局共享、服务端组件、流式渲染等方面需要额外约定。App Router 把这些能力纳入同一套路由树:layout 持久化、page 映射叶子路由、loading/error 提供边界。对团队而言,这意味着更少的「全局壳子」重复代码,以及更清晰的加载与错误策略。

与 Pages Router 的共存

Next.js 允许 apppages 并存一段时间。迁移策略通常是:新功能走 app,旧页面逐步搬迁;或按业务域切分路由段。注意 URL 不能冲突,且两套目录的数据获取与 Head 管理方式不同,需要单独验证 SEO 与统计埋点。

路由与文件约定

app 下的每个文件夹是一个 segmentpage.tsx 暴露为可访问路由;layout.tsx 包裹本段及子段;route.ts 暴露 HTTP 端点。动态段使用 [slug],拦截路由、并行路由属于进阶能力,可在稳定迁移后再引入。

layout 与 template 的差别

layout 在导航切换时保持状态(例如滚动位置、内部表单草稿);template 每次导航会重新挂载子树。默认优先使用 layout;当你明确需要每次进入都重置局部状态时,再考虑 template

服务端组件与客户端组件

Server Components 是默认。它们可以直接 async,在服务端拉取数据并输出 HTML,减少浏览器端 JS 体积。只有在需要事件处理、useState、浏览器 API 或第三方仅客户端库时,才在文件顶上加 use client 或把交互拆到子组件。

组合模式

常见写法是:页面为服务端组件,内部引入若干小的 Client Component(表单、对话框、图表)。避免在根 layout 大面积标记 use client,否则容易把整个子树打包进客户端 bundle。

数据获取与缓存语义

在服务端组件中,fetch 默认会利用 Next 的缓存策略(可按路由段配置 revalidate 或动态渲染)。访问数据库时,优先在服务端完成查询,不要把密钥带进浏览器。若需要客户端轮询或乐观更新,把数据层放在 Client Component,并配合 Route Handler 或 BFF。

与外部 API 协作

对内网服务或第三方 API,注意超时、重试与错误映射;在服务端集中处理鉴权头,避免把 token 暴露给前端。对可缓存的公开内容,可结合 fetchnext: { revalidate } 做增量更新。

loading、Suspense 与流式渲染

loading.tsx 会在对应段展示占位 UI,并与 React Suspense 协作实现流式输出。对首屏关键路径,尽量让首包尽快可见;次要模块可拆到独立 Suspense 边界,减少「全页白屏」时间。

错误与兜底

error.tsx 提供错误边界,可记录日志并给用户可恢复路径。对动态路由,若数据源偶发失败,边界内降级 UI 往往比整页 500 更可接受。

迁移 Checklist

  • 列出所有路由与布局嵌套关系,标出共享壳与仅页面级 UI。
  • 标注哪些页面必须客户端交互,拆出最小 use client 子树。
  • 核对 metadata/generateMetadata 与旧站 SEO 字段。
  • 压测关键接口与 TTFB,确认服务端数据路径无 N+1。
  • 预发环境跑一遍 next build,检查动态/静态划分是否符合预期。

小结

App Router 的价值在于把路由结构、渲染边界与数据路径绑在同一棵树上。先想清楚「默认服务端、局部客户端」的分工,再谈具体语法,迁移会顺很多。后续若你使用国际化、并行路由或 Server Actions,可在稳定主干后再逐项引入。