Next.js

React 生产级全栈框架 - Server Components,基于文件的路由,默认高性能

TL;DR

一句话:Next.js 是生产级 React——让 React 应用默认就很快的全栈框架。

核心优势

  • Server Components - 服务端获取数据,减少 JS 体积
  • 文件路由 - 创建文件就有路由,自动配置
  • Turbopack - 极快的构建(快 2-10 倍)
  • Vercel 原生 - 零配置部署

Core Concepts

概念 1:服务端 vs 客户端组件

默认组件在服务端运行。需要交互时加 'use client'

// 服务端组件(默认)- 可以直接获取数据
async function ProductList() {
  const products = await db.query('SELECT * FROM products');
  return <ul>{products.map(p => <li key={p.id}>{p.name}</li>)}</ul>;
}

// 客户端组件 - 用于交互
'use client';
function Counter() {
  const [count, setCount] = useState(0);
  return <button onClick={() => setCount(c => c + 1)}>{count}</button>;
}

概念 2:App Router

基于文件系统的路由,使用 page.tsx 文件:

app/
├── page.tsx           → /
├── about/page.tsx     → /about
├── blog/[slug]/page.tsx → /blog/:slug(动态)
├── api/users/route.ts  → /api/users(API 端点)
└── layout.tsx         → 共享布局

概念 3:数据获取

直接在服务端组件中获取数据——不需要 useEffect。

// 在组件里直接 async/await
async function Page() {
  const data = await fetch('https://api.example.com/data');
  return <div>{data.title}</div>;
}

Quick Start

创建项目

npx create-next-app@latest my-app
cd my-app
npm run dev

项目结构

my-app/
├── app/
│   ├── page.tsx        # 首页
│   ├── layout.tsx      # 根布局
│   └── globals.css
├── public/             # 静态文件
├── next.config.js
└── package.json

最小示例

// app/page.tsx
export default function Home() {
  return (
    <main>
      <h1>Hello Next.js!</h1>
    </main>
  );
}

运行

npm run dev
# 打开 http://localhost:3000

Gotchas

’use client’ 向下传染

// 如果父组件是服务端组件,子组件可以是任意类型
// 如果父组件是客户端组件,子组件也必须是客户端的

// ✅ 服务端组件使用客户端组件
import ClientButton from './ClientButton';
async function ServerPage() {
  const data = await fetchData();
  return <div>{data}<ClientButton /></div>;
}

动态路由参数在 Next.js 15+ 中是异步的

// app/blog/[slug]/page.tsx
export default async function Page({
  params,
}: {
  params: Promise<{ slug: string }>
}) {
  const { slug } = await params;
  return <h1>文章: {slug}</h1>;
}

Next.js 15+ 中缓存行为改变

// fetch() 默认不再缓存
const data = await fetch(url);  // 不缓存

// 手动开启缓存
const data = await fetch(url, { cache: 'force-cache' });

// 或使用 unstable_cache 缓存非 fetch 数据
import { unstable_cache } from 'next/cache';
const getCachedData = unstable_cache(async () => db.query(...));

API 路由和 Route Handlers

// app/api/users/route.ts
import { NextResponse } from 'next/server';

export async function GET() {
  return NextResponse.json({ users: [] });
}

export async function POST(request: Request) {
  const body = await request.json();
  return NextResponse.json({ created: body });
}

When to Use

适合

  • 生产级 React 应用
  • SEO 关键的网站
  • 带 API 路由的全栈应用
  • 想要开箱即用 React 的团队

不适合

  • 简单静态站点(用 Astro)
  • 非 React 团队(Vue 用 Nuxt)
  • 需要完全控制打包的项目(直接用 Vite)

对比

特性Next.jsRemixAstro
框架ReactReact多框架
SSR可选
侧重全栈Web 标准内容站点
学习曲线中等中等简单

Next Steps

Cheatsheet

模式代码
页面app/route/page.tsx
布局app/layout.tsx
API 路由app/api/route/route.ts
动态路由app/[slug]/page.tsx
通配路由app/[...slug]/page.tsx
加载状态app/loading.tsx
错误处理app/error.tsx
元数据export const metadata = { title: '...' }
重定向redirect('/path')
重验证revalidatePath('/path')