文档
Next.js App Router 全栈之旅
背景
Next.js 是 React 生态的全栈元框架,由 Vercel 维护。App Router(v13+)是它的新路由范式,基于 React Server Components,默认在服务端执行。
核心概念
1. Server vs Client Components
// 默认:服务端组件(无 'use client' 声明)
// 可直接 async/await 数据库查询,不需要 useEffect
export default async function Page() {
const data = await db.query('SELECT * FROM posts')
return <div>{data.map(...)}</div>
}
'use client'
// 客户端组件:需要交互(useState/onClick/useEffect)
import { useState } from 'react'
export default function SearchInput() {
const [query, setQuery] = useState('')
return <input value={query} onChange={e => setQuery(e.target.value)} />
}
2. 文件路由
app/
page.tsx → /
layout.tsx → 根布局
about/page.tsx → /about
blog/[slug]/page.tsx → /blog/:slug
api/posts/route.ts → /api/posts (API 端点)
loading.tsx → 路由级加载态
error.tsx → 路由级错误边界
3. 渲染策略
| 策略 | 用途 | 配置 |
|---|---|---|
| SSR | 每请求渲染 | 默认(服务端组件无缓存即 SSR) |
| SSG | 构建时生成 | generateStaticParams() |
| ISR | 定时增量再生 | fetch(... { next: { revalidate: 60 } }) 或 export const revalidate = 60 |
| PPR | 部分预渲染 | 实验性 |
4. Server Actions
// 直接在服务端处理表单,无需建 API 端点
async function createPost(formData: FormData) {
'use server'
const title = formData.get('title')
await db.post.create({ data: { title } })
}
export default function NewPost() {
return (
<form action={createPost}>
<input name="title" />
<button type="submit">创建</button>
</form>
)
}
5. 数据获取模式
// 服务端组件直接 await 数据库
export default async function PostsPage() {
const posts = await prisma.post.findMany()
return posts.map(p => <PostCard key={p.id} post={p} />)
}
// 客户端用 SWR / React Query
分步操作
npx create-next-app@latest grad-project --typescript --tailwind --app
cd grad-project
npm run dev
思考题
- Server Component 中能不能用
useState?为什么? layout.tsx和template.tsx区别是什么?- 何时用 Server Actions,何时用 API Routes?
毕设场景
- 全栈博客/CMS
- AI 聊天应用(Vercel AI SDK)
- 电商(Next.js Commerce)
- 部署到 Vercel 免费,含域名