Next.js 15完整入门教程

从零开始学习Next.js 15框架,掌握React服务端渲染、静态站点生成和全栈开发,构建高性能的React应用

📑 文章目录

Next.js 15是React生态中最受欢迎的全栈框架,它提供了服务端渲染、静态站点生成、API路由等强大功能。本教程将从零开始,带你掌握Next.js 15的核心概念和实战技巧。

快速开始

让我们从创建第一个Next.js 15项目开始。

创建项目

使用官方脚手架创建新项目:

# 使用yarn创建项目
yarn create next-app my-app

# 或使用npx
npx create-next-app@latest my-app

创建时配置选项

创建过程中会询问以下配置:

✔ Would you like to use ESLint? Yes
✔ Would you like to use Tailwind CSS? Yes
✔ Would you like to use `src/` directory? Yes
✔ Would you like to use App Router? Yes
✔ Would you like to customize the default import alias (@/*)? No

项目结构

Next.js 15的项目结构如下:

my-app/
├── app/
│   ├── layout.tsx          # 根布局(所有页面共用)
│   ├── page.tsx            # / - 首页
│   ├── about/
│   │   └── page.tsx        # /about - 关于页面
│   └── blog/
│       └── [slug]/
│           └── page.tsx    # /blog/[slug] - 动态路由
├── public/                 # 静态资源
├── styles/                 # 全局样式
├── package.json
└── next.config.js

运行开发服务器

npm install

# 运行开发服务器
npm run dev

App Router

Next.js 13引入了App Router,基于React Server Components,提供了更好的性能和开发体验。

路由示例

app/
├── layout.tsx              # 根布局(所有页面共用)
├── page.tsx                # / - 首页
├── about/
│   └── page.tsx            # /about - 关于页面
└── blog/
    └── [slug]/
        └── page.tsx        # /blog/[slug] - 动态路由

Layout组件

Layout组件定义页面的共享UI:

import type { Metadata } from 'next'
import './globals.css'

export const metadata: Metadata = {
  title: 'My App',
  description: 'My App Description'
}

export default function RootLayout({
  children,
}: {
  children: React.ReactNode
}) {
  return (
    <html lang="zh">
      <body>{children}</body>
    </html>
  )
}

Page组件

Page组件定义具体页面的内容:

export default function Home() {
  return (
    <div>
      <h1>欢迎来到我的网站</h1>
      <p>这是首页内容</p>
    </div>
  )
}

Server Components

Server Components在服务器端渲染,可以减少JavaScript bundle大小,提升性能。

数据获取

Server Components可以直接获取数据:

async function getUser() {
  const res = await fetch('https://api.example.com/user')
  return res.json()
}

export default async function Profile() {
  const user = await getUser()
  return <div>Hello, {user.name}!</div>
}

💡 Server Components vs Client Components

默认情况下所有组件都是Server Components。需要使用React hooks、事件处理器等特性的组件需要标记为客户端组件。

客户端组件

'use client'

import { useState } from 'react'

export default function Counter() {
  const [count, setCount] = useState(0)
  
  return (
    <button onClick={() => setCount(count + 1)}>
      点击次数: {count}
    </button>
  )
}

数据获取

Next.js 15提供了多种数据获取策略。

静态生成(Static Generation)

在构建时预渲染页面:

export default async function BlogList() {
  const posts = await fetch('https://api.example.com/posts').then(r => r.json())
  
  return (
    <div>
      {posts.map(post => (
        <article key={post.id}>{post.title}</article>
      ))}
    </div>
  )
}

// 或者在页面级别配置
export const dynamic = 'force-static'

服务端渲染(Server-Side Rendering)

每次请求时在服务端渲染:

export default async function DynamicData() {
  const data = await fetch('https://api.example.com/data', {
    cache: 'no-store'  // 禁用缓存
  })
  
  return <div>{data.message}</div>
}

// 或者在页面级别配置
export const dynamic = 'force-dynamic'

增量静态生成(ISR)

在构建后定期重新生成页面:

export default async function ISRPage() {
  const data = await fetch('https://api.example.com/data').then(r => r.json())
  
  return <div>{data.content}</div>
}

export const revalidate = 3600  // 1小时后重新生成

并行数据获取

同时获取多个数据源:

export default async function Dashboard() {
  const [users, posts] = await Promise.all([
    fetch('https://api.example.com/users').then(r => r.json()),
    fetch('https://api.example.com/posts').then(r => r.json())
  ])
  
  return (
    <div>
      <Users users={users} />
      <Posts posts={posts} />
    </div>
  )
}

路由系统

Next.js 15的路由系统功能强大且灵活。

动态路由

// app/blog/[slug]/page.tsx
export default async function BlogPost({
  params
}: {
  params: { slug: string }
}) {
  const res = await fetch(`https://api.example.com/posts/${params.slug}`)
  const post = await res.json()
  
  return <article>{post.content}</article>
}

路由跳转

import Link from 'next/link'

export default function Navigation() {
  return (
    <nav>
      <Link href="/">首页</Link>
      <Link href="/about">关于</Link>
      <Link href="/blog">博客</Link>
    </nav>
  )
}

编程式导航

'use client'

import { useRouter } from 'next/navigation'

export function NavigateButton() {
  const router = useRouter()
  
  return (
    <button onClick={() => router.push('/about')}>
      前往关于页面
    </button>
  )
}

API Routes

Next.js 15允许你在同一个项目中创建API端点。

创建API Route

// app/api/hello/route.ts
export async function GET() {
  return NextResponse.json({ message: 'Hello from Next.js!' })
}

动态API Route

// app/api/users/[id]/route.ts
export async function GET(
  request: Request,
  { params }: { params: { id: string } }
) {
  const user = await getUserById(params.id)
  return NextResponse.json(user)
}

错误处理

export async function GET() {
  try {
    const data = await fetchData()
    return NextResponse.json(data)
  } catch (error) {
    return NextResponse.json(
      { error: '获取数据失败' },
      { status: 500 }
    )
  }
}

样式方案

Next.js 15支持多种样式方案。

CSS Modules

// styles/Home.module.css
.container {
  padding: 2rem;
}

// app/page.tsx
import styles from './page.module.css'

export default function Page() {
  return (
    <div className={styles.container}>
      首页内容
    </div>
  )
}

Tailwind CSS

<div className="bg-white rounded-lg shadow-md p-6">
  <h2 className="text-2xl font-bold mb-4">标题</h2>
  <p className="text-gray-600">内容</p>
</div>

Styled JSX

export default function Component() {
  return (
    <>
      <div>内容</div>
      <style jsx>{
        `
          div {
            color: red;
          }
        `
      }</style>
    </>
  )
}

部署上线

Next.js 15支持多种部署方式。

Vercel部署

Vercel是Next.js的官方平台:

# 安装Vercel CLI
npm install -g vercel

# 部署项目
vercel

Docker部署

# Dockerfile
FROM node:18-alpine AS base

# Install dependencies only when needed
FROM base AS deps
RUN apk add --no-cache libc6-compat
WORKDIR /app

COPY package.json package-lock.json ./
RUN npm ci

# Rebuild the source code only when needed
FROM base AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
RUN npm run build

# Production image, copy all the files and run next
FROM base AS runner
WORKDIR /app
ENV NODE_ENV production

RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjs

COPY --from=builder /app/public ./public
COPY --from=builder /app/.next/standalone ./
COPY --from=builder /app/.next/static ./.next/static

USER nextjs
EXPOSE 3000
ENV PORT 3000
CMD ["node", "server.js"]

⚠️ 部署注意事项

部署前确保配置了正确的环境变量,特别是数据库连接、API密钥等敏感信息。生产环境建议使用环境变量管理配置。

结语

Next.js 15为React开发带来了革命性的改进,特别是App Router和Server Components让全栈开发变得更加简单高效。

通过本教程,你应该已经掌握了Next.js 15的核心概念和基本用法。接下来建议你:

  • 动手实践,创建一个完整的项目
  • 深入学习高级特性,如中间件、国际化等
  • 关注官方文档和更新,及时了解新特性
  • 参与社区,与其他开发者交流经验

Next.js的生态正在快速发展,掌握它将为你的前端开发生涯开启新的篇章!

分享文章