人人都会AI编程

24.2 Next.js 核心体系

更新时间:2026-07-11

Next.js 是目前 React 生态中最成熟的全栈框架,它基于 React 构建,但提供了路由、数据获取、渲染策略、API 路由等一站式解决方案。对于需要 SEO、首屏性能优化或复杂后端逻辑的 React 应用,Next.js 几乎是首选方案。

路由系统

Next.js 的路由基于文件系统,即 pagesapp 目录下的文件结构直接映射为应用的路由。这种约定大于配置的设计让路由组织一目了然,无需额外安装路由库。

Pages Router(传统路由)

pages 目录下,每个 .js/.tsx 文件自动成为一个路由:

pages/
  index.tsx        → /
  about.tsx        → /about
  blog/
    index.tsx      → /blog
    [slug].tsx     → /blog/:slug (动态路由)
  • 动态路由:使用 [param] 语法,pages/posts/[id].tsx 匹配 /posts/1/posts/abc 等。
  • 嵌套路由:通过目录层级自然实现,pages/dashboard/settings.tsx/dashboard/settings
  • 浅层路由:允许改变 URL 而不重新触发数据获取,适合筛选参数等场景。

示例:动态路由页

// pages/posts/[id].tsx
import { useRouter } from 'next/router';

export default function Post() {
  const router = useRouter();
  const { id } = router.query;

  return <div>文章 ID: {id}</div>;
}

App Router(新路由)

Next.js 13 引入了基于 app 目录的新路由系统,采用 React Server Components 架构,更加强大和灵活:

app/
  layout.tsx       → 根布局(所有页面共享)
  page.tsx         → /
  about/
    page.tsx       → /about
  blog/
    layout.tsx     → /blog 下的布局
    page.tsx       → /blog
    [slug]/
      page.tsx     → /blog/:slug
  • 约定文件page.tsx(页面内容)、layout.tsx(布局,保持状态)、loading.tsx(加载态)、error.tsx(错误边界)、not-found.tsx(404)。
  • 动态路由[id] 单段动态,[...slug] 捕获所有后续路径段。
  • 并行路由与拦截路由:支持高级 UI 模式,如模态框的独立路由。

App Router 示例:

// app/blog/[slug]/page.tsx
export default async function BlogPost({ params }) {
  const { slug } = params;
  // 可以直接在服务端获取数据,无需客户端 hooks
  const post = await fetchPost(slug);
  return <article>{post.content}</article>;
}

App Router 默认启用服务端组件,数据获取可以直接在组件内进行,减少了客户端 bundle 大小,性能更好。

数据获取(Data Fetching)

Next.js 提供了多种数据获取方式,适合不同的渲染策略。

Pages Router 数据获取

  • getStaticProps:在构建时运行,获取静态生成所需的数据。返回的 props 会注入到页面组件。
  • getServerSideProps:在每个请求时运行,用于服务端渲染,可以获取实时数据。
  • getStaticPaths:配合动态路由静态生成,返回所有可能的路径。

示例(静态生成):

export async function getStaticProps() {
  const posts = await fetch('https://api.example.com/posts').then(res => res.json());
  return { props: { posts }, revalidate: 60 }; // ISR:60秒后可在后台重新生成页面
}

export default function Blog({ posts }) {
  // ...
}

App Router 数据获取

App Router 直接利用 async 组件和 fetch 的缓存策略。数据获取变得更简洁:

  • 组件可以直接 await 数据,Next.js 自动处理缓存和重新验证。
  • 可以精细控制缓存:fetch(url, { cache: 'force-cache' | 'no-store' })
  • revalidate 配置支持 ISR。

示例:

// app/posts/page.tsx
async function getPosts() {
  const res = await fetch('https://api.example.com/posts', { next: { revalidate: 60 } });
  return res.json();
}

export default async function PostsPage() {
  const posts = await getPosts();
  return <ul>{posts.map(post => <li key={post.id}>{post.title}</li>)}</ul>;
}

这种方式消除了对 getStaticProps 这类专用函数的依赖,心智负担更低。

静态生成(SSG: Static Site Generation)

静态生成指在构建时生成完整的 HTML 页面,然后这些页面可以被 CDN 缓存和快速分发。它是内容变化不频繁的场景下性能最优的选择,比如博客、文档站、产品介绍页。

Next.js 默认就会尝试对没有阻塞数据请求的页面进行静态生成(App Router 优先静态)。

如何实现静态生成

  • Pages Router:使用 getStaticProps,如果没有该函数但页面没有服务端依赖,也会自动静态生成。
  • App Router:组件默认就是服务端组件且无动态行为时,会自动静态渲染。可以通过 export const dynamic = 'force-static' 强制静态。

ISR(增量静态再生成):允许在运行时重新生成静态页面,无需完整重建整个站点。在 getStaticProps 中设置 revalidate 或在 fetch 中配置 next.revalidate 即可。

示例:

// 构建时生成页面,最多每60秒重新验证一次
export async function getStaticProps() {
  const data = await fetch('...');
  return { props: { data }, revalidate: 60 };
}

这种策略兼顾了静态页面的性能和动态数据的实时性。

服务端渲染(SSR: Server-Side Rendering)

服务端渲染指每次请求时在服务器上生成 HTML 返回给客户端。适合需要最新数据且 SEO 重要的页面,比如新闻页、个性化首页、支付结果页。

Pages Router 中的 SSR

使用 getServerSideProps 函数:

export async function getServerSideProps(context) {
  const { req, res } = context;
  const data = await fetchDataBasedOnAuth(req.cookies.token);
  return { props: { data } };
}

每个请求都会运行该函数,所以能拿到最新的请求信息(cookies、URL 参数等),但服务器负载较高,响应时间受 API 调用耗时影响。

App Router 中的 SSR

在 App Router 中,通过使用动态函数或设置动态渲染选项来触发 SSR:

// app/page.tsx
import { cookies } from 'next/headers';

export default async function Page() {
  const cookieStore = cookies(); // 动态函数,强制该路由动态渲染
  const data = await fetch('...');
  // ...
}

也可以显式设置:export const dynamic = 'force-dynamic'

优势:App Router 支持流式渲染,配合 Suspense 可向客户端提前发送部分 HTML,提升感知性能。

总结对比

| 策略 | 适用场景 | 数据获取方式 | 首屏性能 | SEO |
|------|----------|--------------|----------|-----|
| 静态生成(SSG) | 内容不频繁变化 | 构建时 | 极快(CDN) | 好 |
| 服务端渲染(SSR) | 实时数据、个性化 | 每次请求 | 较快 | 好 |
| 增量静态生成(ISR) | 内容定期更新 | 构建时 + 后台更新 | 快 | 好 |
| 客户端渲染(CSR) | 后台系统、交互密集 | 客户端请求 | 慢(白屏) | 差 |

Next.js 让这些策略的选择变得灵活,你甚至可以在同一应用内对不同页面使用不同的渲染方式,真正实现最佳平衡。