跳转至

Next.js 全栈框架

一句话概述:Next.js 是基于React的全栈Web框架,由Vercel开发,提供服务端渲染(SSR)、静态生成(SSG)、API路由等开箱即用的功能。

核心知识点表

概念白话解释
App RouterNext.js 13+的路由系统,用文件夹结构定义页面路由
Server Component服务端组件,在服务器上渲染,不发JavaScript到浏览器
Client Component客户端组件,在浏览器运行,需要交互的组件用这个
Server Action在组件里直接写服务端函数,不需要单独建API
SSR服务端渲染,每次请求时在服务器生成HTML
SSG静态生成,构建时生成HTML,最快
ISR增量静态再生,定时更新静态页面
PPR部分预渲染(Partial Prerendering),静态壳+动态流
Middleware中间件,在请求到达页面之前执行逻辑(鉴权等)
Turbopack替代Webpack的新打包器,极快

版本信息(2026年5月)

  • Next.js 16(2025年10月发布,当前最新大版本)
  • React 19 支持、React Compiler稳定、PPR接近GA
  • Turbopack生产构建已稳定

安装配置

# 创建Next.js项目(推荐方式)
npx create-next-app@latest my-app  # 交互式创建
# 选项建议:
# TypeScript → Yes
# ESLint → Yes
# Tailwind CSS → Yes
# src/ directory → Yes
# App Router → Yes(推荐)
# Turbopack → Yes(新项目推荐)

cd my-app  # 进入项目

# 启动开发服务器
npm run dev  # 访问 http://localhost:3000

项目结构(App Router)

my-app/
├── src/
│   ├── app/                    # App Router目录
│   │   ├── layout.tsx          # 根布局(所有页面共享)
│   │   ├── page.tsx            # 首页 → /
│   │   ├── about/
│   │   │   └── page.tsx        # 关于页 → /about
│   │   ├── blog/
│   │   │   ├── page.tsx        # 博客列表 → /blog
│   │   │   └── [slug]/
│   │   │       └── page.tsx    # 博客详情 → /blog/xxx
│   │   ├── api/
│   │   │   └── users/
│   │   │       └── route.ts    # API路由 → /api/users
│   │   └── globals.css         # 全局样式
│   └── components/             # 可复用组件
├── public/                     # 静态资源
├── next.config.ts              # Next.js配置
└── package.json

基本使用

页面和布局

// src/app/layout.tsx — 根布局
export default function RootLayout({
  children,  // 子页面内容
}: {
  children: React.ReactNode
}) {
  return (
    <html lang="zh">
      <body>
        <nav>导航栏</nav>  {/* 所有页面都有的导航 */}
        {children}          {/* 这里放具体页面内容 */}
        <footer>底部</footer>
      </body>
    </html>
  )
}

// src/app/page.tsx — 首页(默认是Server Component)
export default function HomePage() {
  return (
    <main>
      <h1>欢迎来到我的网站</h1>
      <p>这是一个Server Component在服务器上渲染</p>
    </main>
  )
}

Server Component(服务端组件)

// src/app/users/page.tsx
// 默认就是Server Component,可以直接查数据库!

async function getUsers() {
  // 直接在组件里查数据库或调API
  const res = await fetch('https://api.example.com/users')
  return res.json()
}

export default async function UsersPage() {
  const users = await getUsers()  // 服务端执行,不暴露给浏览器

  return (
    <ul>
      {users.map((user: any) => (
        <li key={user.id}>{user.name}</li>
      ))}
    </ul>
  )
}

Client Component(客户端组件)

// src/components/Counter.tsx
'use client'  // 加这行声明为客户端组件

import { useState } from 'react'  // 客户端才能用hooks

export default function Counter() {
  const [count, setCount] = useState(0)  // 状态管理

  return (
    <div>
      <p>计数: {count}</p>
      <button onClick={() => setCount(count + 1)}>+1</button>
    </div>
  )
}

Server Action

// src/app/contact/page.tsx
// Server Action:在组件里直接写服务端逻辑

export default function ContactPage() {
  // 这个函数在服务器上执行!
  async function submitForm(formData: FormData) {
    'use server'  // 标记为Server Action

    const name = formData.get('name') as string
    const email = formData.get('email') as string

    // 直接操作数据库
    // await db.insert({ name, email })
    console.log(`收到: ${name}, ${email}`)
  }

  return (
    <form action={submitForm}>
      <input name="name" placeholder="姓名" required />
      <input name="email" type="email" placeholder="邮箱" required />
      <button type="submit">提交</button>
    </form>
  )
}

API路由

// src/app/api/users/route.ts
import { NextRequest, NextResponse } from 'next/server'

// GET /api/users
export async function GET() {
  const users = [
    { id: 1, name: 'Alice' },
    { id: 2, name: 'Bob' },
  ]
  return NextResponse.json(users)  // 返回JSON
}

// POST /api/users
export async function POST(request: NextRequest) {
  const body = await request.json()  // 解析请求体
  // 保存到数据库...
  return NextResponse.json(
    { message: '创建成功', data: body },
    { status: 201 }
  )
}

高级用法

动态路由

// src/app/blog/[slug]/page.tsx
// [slug] 是动态参数,匹配 /blog/xxx

type Props = {
  params: Promise<{ slug: string }>
}

export default async function BlogPost({ params }: Props) {
  const { slug } = await params  // 获取URL参数
  const post = await fetch(`https://api.example.com/posts/${slug}`).then(r => r.json())

  return (
    <article>
      <h1>{post.title}</h1>
      <p>{post.content}</p>
    </article>
  )
}

// 静态生成:构建时预生成所有博客页面
export async function generateStaticParams() {
  const posts = await fetch('https://api.example.com/posts').then(r => r.json())
  return posts.map((post: any) => ({
    slug: post.slug,  // 返回所有可能的slug值
  }))
}

Middleware中间件

// src/middleware.ts(根目录)
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'

export function middleware(request: NextRequest) {
  // 检查是否登录
  const token = request.cookies.get('token')

  if (!token && request.nextUrl.pathname.startsWith('/dashboard')) {
    // 未登录访问dashboard,重定向到登录页
    return NextResponse.redirect(new URL('/login', request.url))
  }

  return NextResponse.next()  // 继续处理请求
}

// 配置中间件生效的路径
export const config = {
  matcher: ['/dashboard/:path*', '/api/protected/:path*'],
}

数据缓存与重验证

// 缓存策略
const data1 = await fetch(url)  // 默认缓存(静态)
const data2 = await fetch(url, { cache: 'no-store' })  // 不缓存(动态)
const data3 = await fetch(url, { next: { revalidate: 60 } })  // 60秒后重新验证

常见报错与解决

报错信息原因解决方案
useState is not allowed in Server Components在Server Component里用了hooks'use client'声明为Client Component
Error: Dynamic server usage在静态页面中使用了动态函数export const dynamic = 'force-dynamic'
Module not found包没安装或路径错误npm install xxx或检查import路径
Hydration mismatch服务端和客户端渲染结果不同检查是否有依赖浏览器API的代码
NEXT_REDIRECTredirect()在错误上下文中调用在Server Action或Server Component中使用

速查表

# ===== CLI命令 =====
npx create-next-app@latest     # 创建项目
npm run dev                     # 开发模式
npm run build                   # 构建
npm run start                   # 生产模式启动
npm run lint                    # 代码检查

# ===== 文件路由约定 =====
# page.tsx        页面组件
# layout.tsx      布局(嵌套)
# loading.tsx     加载UI
# error.tsx       错误UI
# not-found.tsx   404页面
# route.ts        API路由
# middleware.ts   中间件

# ===== 特殊导出 =====
# export const dynamic = 'force-dynamic'  // 强制动态渲染
# export const revalidate = 60            // ISR: 60秒重验证
# export async function generateStaticParams()  // 静态路径
# export async function generateMetadata()      // SEO元数据

同类工具对比

特性Next.jsNuxtSvelteKitAstroRemix
基于ReactVueSvelte多框架React
SSR支持支持支持支持支持
SSG支持支持支持默认有限
生态最大Vue生态增长中丰富React
学习曲线中等较低较低中等
适合全栈应用Vue项目高性能应用内容站复杂交互

面试建议:Next.js是React全栈开发的首选。面试重点:1)Server Component vs Client Component的区别和使用场景;2)SSR/SSG/ISR的区别;3)App Router vs Pages Router;4)Server Action简化了什么。