1722 字
9 分钟
Next.js 全栈开发入门:从零搭建一个现代 Web 应用

1. 引言#

Next.js 是目前最流行的 React 全栈框架。它把 React 的组件化能力扩展到了服务端,让你可以在同一个项目里写前端页面和后端 API。

回顾上一篇文章我们讲的三种渲染模式(CSR / SSR / SSG),Next.js 的独特之处在于:它让这三种模式在同一个项目中无缝协作 —— 你可以按页面粒度决定渲染策略。


2. 创建第一个 Next.js 项目#

2.1 初始化#

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

初始化向导会问你几个问题:

✔ Would you like to use TypeScript? Yes
✔ Would you like to use ESLint? Yes
✔ Would you like to use Tailwind CSS? Yes
✔ Would you like to use App Router? Yes(推荐)

启动后访问 http://localhost:3000,第一个 Next.js 项目就跑起来了。

2.2 项目结构#

my-blog/
├── app/ # App Router 的核心目录
│ ├── layout.tsx # 根布局(所有页面共享)
│ ├── page.tsx # 首页 /
│ ├── about/
│ │ └── page.tsx # /about
│ ├── blog/
│ │ ├── page.tsx # /blog
│ │ └── [slug]/
│ │ └── page.tsx # /blog/hello-world
│ └── api/
│ └── posts/
│ └── route.ts # /api/posts
├── components/ # 公共组件
├── lib/ # 工具函数
├── public/ # 静态资源
├── package.json
└── next.config.ts

核心规则:文件系统即路由。 app/ 目录下的文件夹结构直接映射为 URL 路径。


3. App Router:文件即路由#

3.1 基础约定#

文件作用
page.tsx页面内容
layout.tsx布局(包裹子页面,切换页面时保持状态)
loading.tsx加载中的 UI(自动包裹 Suspense
error.tsx错误处理 UI(自动包裹 ErrorBoundary
not-found.tsx404 页面
route.tsAPI 路由(纯后端)

3.2 路由示例#

app/
├── page.tsx → /
├── about/page.tsx → /about
├── blog/page.tsx → /blog
├── blog/[slug]/page.tsx → /blog/hello, /blog/world
└── dashboard/
├── layout.tsx → dashboard 共享布局
├── page.tsx → /dashboard
└── settings/page.tsx → /dashboard/settings

3.3 动态路由和参数#

app/blog/[slug]/page.tsx
export default async function BlogPost({
params,
}: {
params: Promise<{ slug: string }>;
}) {
const { slug } = await params;
const post = await getPost(slug);
return (
<article>
<h1>{post.title}</h1>
<p>{post.content}</p>
</article>
);
}

URL /blog/hello-worldslug = "hello-world"


4. Server Components vs Client Components#

Next.js 13+ 引入了React Server Components(RSC),这是理解现代 Next.js 的关键。

4.1 默认是服务端组件#

// ✅ 这是 Server Component(默认)
// 可以直接访问数据库、文件系统
import { db } from '@/lib/db';
export default async function PostList() {
const posts = await db.post.findMany(); // 直接查数据库!
return (
<ul>
{posts.map(post => (
<li key={post.id}>{post.title}</li>
))}
</ul>
);
}

4.2 需要交互时用客户端组件#

'use client'; // ← 加这一行,变为客户端组件
import { useState } from 'react';
export default function LikeButton() {
const [likes, setLikes] = useState(0);
return (
<button onClick={() => setLikes(likes + 1)}>
❤️ {likes} 赞
</button>
);
}

4.3 什么时候用哪个?#

需求用哪种组件
从数据库获取数据Server Component
展示静态内容Server Component
处理用户交互(onClick、onChange…)Client Component
使用状态(useState、useReducer)Client Component
使用浏览器 API(localStorage、window)Client Component
使用 Effect(useEffect)Client Component

最佳实践:尽可能使用 Server Component,只在必要处添加客户端交互。 这样可以最小化发往客户端的 JS 体积,获得最佳性能。


5. 数据获取#

5.1 在 Server Component 中直接获取#

app/posts/page.tsx
// 无需 useEffect + useState,直接 async/await
export default async function PostsPage() {
const posts = await fetch('https://api.example.com/posts', {
next: { revalidate: 3600 }, // ISR:每小时重新验证
}).then(res => res.json());
return (
<div>
{posts.map(post => (
<article key={post.id}>
<h2>{post.title}</h2>
<p>{post.excerpt}</p>
</article>
))}
</div>
);
}

5.2 Next.js 增强了 fetch#

Next.js 扩展了原生的 fetch API,增加了缓存控制:

// 缓存,默认行为(类似 SSG)
fetch('/api/data');
// 每次请求重新获取(类似 SSR)
fetch('/api/data', { cache: 'no-store' });
// 定时重新验证(ISR — 增量静态再生)
fetch('/api/data', { next: { revalidate: 60 } }); // 60秒

5.3 使用 ORM 直接操作数据库#

因为 Server Component 运行在服务器上,你可以直接使用 Prisma、Drizzle 等 ORM:

app/users/page.tsx
import { prisma } from '@/lib/prisma';
export default async function UsersPage() {
const users = await prisma.user.findMany({
orderBy: { createdAt: 'desc' },
});
return (
<table>
<thead>
<tr><th>姓名</th><th>邮箱</th></tr>
</thead>
<tbody>
{users.map(user => (
<tr key={user.id}>
<td>{user.name}</td>
<td>{user.email}</td>
</tr>
))}
</tbody>
</table>
);
}

6. API 路由:编写后端接口#

Next.js 不仅仅是前端框架,还能写后端 API:

6.1 创建 API 端点#

app/api/posts/route.ts
import { NextResponse } from 'next/server';
// GET /api/posts
export async function GET() {
const posts = await prisma.post.findMany();
return NextResponse.json(posts);
}
// POST /api/posts
export async function POST(request: Request) {
const body = await request.json();
const post = await prisma.post.create({ data: body });
return NextResponse.json(post, { status: 201 });
}

6.2 动态 API 路由#

app/api/posts/[id]/route.ts
export async function GET(
request: Request,
{ params }: { params: Promise<{ id: string }> }
) {
const { id } = await params;
const post = await prisma.post.findUnique({ where: { id } });
if (!post) {
return NextResponse.json(
{ error: '文章不存在' },
{ status: 404 }
);
}
return NextResponse.json(post);
}
export async function DELETE(
request: Request,
{ params }: { params: Promise<{ id: string }> }
) {
const { id } = await params;
await prisma.post.delete({ where: { id } });
return NextResponse.json({ success: true });
}

6.3 Server Actions:另一种「后端」方式#

Next.js 还提供了 Server Actions —— 你可以直接在表单里调用服务端函数,无需手动创建 API:

app/actions.ts
'use server';
import { prisma } from '@/lib/prisma';
import { revalidatePath } from 'next/cache';
export async function createPost(formData: FormData) {
const title = formData.get('title') as string;
const content = formData.get('content') as string;
await prisma.post.create({
data: { title, content },
});
revalidatePath('/posts'); // 刷新缓存
}
app/new-post/page.tsx
import { createPost } from '@/app/actions';
export default function NewPostPage() {
return (
<form action={createPost}>
<input name="title" placeholder="标题" required />
<textarea name="content" placeholder="内容" required />
<button type="submit">发布</button>
</form>
);
}

7. 渲染策略实战#

Next.js 支持按页面粒度选择渲染策略:

// 1. SSG(默认)— 构建时生成,永不改变
export default function AboutPage() {
return <div>关于我们</div>;
}
// 2. ISR — 构建时生成,定时刷新
export const revalidate = 3600; // 每3600秒重新生成
// 3. SSR — 每次请求都重新生成
export const dynamic = 'force-dynamic';
// 4. 动态 SSG — 为每条数据预生成页面
export async function generateStaticParams() {
const posts = await getPosts();
return posts.map(post => ({ slug: post.slug }));
}

8. 部署#

Next.js 最自然的部署平台是 Vercel(Next.js 的创造者),但也可以部署到任何支持 Node.js 的环境:

Terminal window
# 生产构建
npm run build
# 启动生产服务器
npm run start
部署方式特点
Vercel零配置,自动优化,全球 CDN
Docker容器化部署,适合自托管
Node.js 服务器传统方式,next start
静态导出next export,纯静态文件放 CDN

9. 学习路线建议#

阶段内容关键概念
入门创建项目、页面路由、基础组件App Router 约定
进阶Server Components、数据获取、API RoutesRSC、缓存策略
实战认证(NextAuth)、数据库(Prisma)、表单Server Actions
深入中间件、国际化、性能优化、错误监控Edge Runtime

10. 小结#

Next.js 的核心价值一句话总结:它把 React 从一个「前端库」升级为「全栈框架」。

传统 React(CSR)Next.js
在浏览器里渲染服务端渲染 + 客户端交互
需要单独搭建后端自带 API Routes / Server Actions
手动配置路由文件系统即路由
SEO 差原生 SEO 友好
单一渲染模式SSG / SSR / ISR 按需选择

学完 HTML/CSS/JavaScript 基础、理解了 React 的组件化思维、弄清了三种渲染模式的区别之后,Next.js 就是你将所有这些知识整合在一起的「最终武器」。从想法到上线,一个仓库就够了。

Next.js 全栈开发入门:从零搭建一个现代 Web 应用
https://www.hehonglei.cn/technology/nextjs-fullstack-intro/
作者
Honglei He
发布于
2026-06-17
许可协议
CC BY-NC-SA 4.0