返回笔记列表

Next.js入门学习笔记

Next.js 入门学习笔记

Next.js 是一个基于 React 的全栈 Web 框架,专为生产环境而设计。它提供了许多开箱即用的功能,使开发 React 应用变得更加简单高效。

为什么选择 Next.js

  1. 零配置:开箱即用,包含了开发所需的大多数功能
  2. 混合渲染:支持多种渲染方式(SSR, SSG, CSR, ISR)
  3. 自动代码拆分:优化加载性能
  4. 内置路由系统:基于文件系统的路由
  5. API 路由:轻松创建后端 API
  6. 开发体验:热更新、TypeScript 支持

安装和创建项目

使用 create-next-app 可以快速创建 Next.js 项目:

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

通过命令行参数可以自定义配置:

npx create-next-app@latest my-next-app --typescript --tailwind --eslint

Next.js 13+ App Router 目录结构

Next.js 13 引入了新的 App Router 系统,以下是基础目录结构:

my-next-app/
├── app/                 # App Router 目录
│   ├── layout.tsx       # 根布局组件
│   ├── page.tsx         # 首页组件
│   ├── about/           # /about 路由
│   │   └── page.tsx     # /about 页面组件
│   ├── blog/            # /blog 路由
│   │   ├── page.tsx     # /blog 页面组件
│   │   └── [id]/        # 动态路由
│   │       └── page.tsx # /blog/[id] 页面组件
├── public/              # 静态文件目录
├── components/          # 组件目录
├── lib/                 # 工具函数和库
├── styles/              # 样式文件
└── next.config.js       # Next.js 配置文件

路由系统

App Router 使用基于文件系统的路由机制,它有以下特点:

  1. 文件约定

    • page.tsx: 页面组件
    • layout.tsx: 布局组件
    • loading.tsx: 加载状态组件
    • error.tsx: 错误处理组件
    • not-found.tsx: 404 页面
  2. 路由类型

    • 静态路由:app/about/page.tsx/about
    • 动态路由:app/blog/[id]/page.tsx/blog/123
    • 捕获所有路由:app/[...slug]/page.tsx → 匹配任何未定义的路由
  3. 嵌套路由:目录结构自然对应路由嵌套层级

布局系统

Next.js 13+ 引入了新的布局系统:

// app/layout.tsx (根布局)
export default function RootLayout({ children }) {
  return (
    <html lang="zh">
      <body>
        <header>网站头部</header>
        <main>{children}</main>
        <footer>网站底部</footer>
      </body>
    </html>
  );
}

// app/blog/layout.tsx (博客布局)
export default function BlogLayout({ children }) {
  return (
    <div>
      <nav>博客导航</nav>
      <section>{children}</section>
    </div>
  );
}

这个系统支持嵌套布局,子布局会包裹在父布局内部。

数据获取方式

Next.js 提供了多种数据获取方式:

1. 服务器组件(默认)

// 这是一个服务器组件
export default async function Page() {
  // 直接在服务器组件中获取数据
  const data = await fetch('https://api.example.com/data');
  const posts = await data.json();
  
  return (
    <div>
      {posts.map(post => (
        <div key={post.id}>{post.title}</div>
      ))}
    </div>
  );
}

2. 客户端组件

'use client'; // 标记为客户端组件

import { useState, useEffect } from 'react';

export default function ClientComponent() {
  const [data, setData] = useState(null);
  
  useEffect(() => {
    async function fetchData() {
      const res = await fetch('/api/data');
      const json = await res.json();
      setData(json);
    }
    fetchData();
  }, []);
  
  return data ? <div>{data.title}</div> : <div>加载中...</div>;
}

渲染策略

Next.js 支持多种渲染策略:

1. 服务端渲染 (SSR)

动态生成页面内容,对 SEO 友好:

// 默认情况下,App Router 使用动态服务端渲染
export default async function Page() {
  const data = await fetch('https://api.example.com/data', { cache: 'no-store' });
  const posts = await data.json();
  
  return <PostList posts={posts} />;
}

2. 静态站点生成 (SSG)

构建时预渲染页面,适合内容不经常变化的网站:

export default async function Page() {
  const data = await fetch('https://api.example.com/data');
  const posts = await data.json();
  
  return <PostList posts={posts} />;
}

3. 增量静态再生成 (ISR)

定期重新生成静态页面:

export default async function Page() {
  const data = await fetch('https://api.example.com/data', { 
    next: { revalidate: 60 } // 每60秒重新验证
  });
  const posts = await data.json();
  
  return <PostList posts={posts} />;
}

API 路由

Next.js 允许创建 API 端点:

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

export async function GET() {
  return NextResponse.json({ message: 'Hello, Next.js!' });
}

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

元数据和 SEO

Next.js 提供了内置的元数据 API:

// app/layout.tsx
import { Metadata } from 'next';

export const metadata: Metadata = {
  title: {
    template: '%s | My Website',
    default: 'My Website',
  },
  description: '我的个人网站',
  openGraph: {
    title: 'My Website',
    description: '我的个人网站',
    images: '/og-image.jpg',
  },
};

export default function RootLayout({ children }) {
  return (
    <html lang="zh">
      <body>{children}</body>
    </html>
  );
}

// app/blog/[id]/page.tsx
import { Metadata } from 'next';

// 动态生成元数据
export async function generateMetadata({ params }) {
  const post = await getPost(params.id);
  
  return {
    title: post.title,
    description: post.excerpt,
  };
}

图像优化

Next.js 内置的 Image 组件可以自动优化图像:

import Image from 'next/image';

export default function Page() {
  return (
    <Image
      src="/profile.jpg"
      alt="Profile Picture"
      width={500}
      height={300}
      priority
    />
  );
}

部署

Next.js 应用可以部署到多种平台:

  1. Vercel:Next.js 的创建者提供的平台,零配置部署
  2. Netlify:支持 Next.js 应用
  3. 自托管:可以导出并部署到任何支持 Node.js 的服务器

总结

Next.js 是一个功能强大的 React 框架,它简化了 React 应用的开发流程,提供了丰富的功能如路由、渲染策略、API 路由等。App Router 的引入进一步改进了开发体验,使构建现代 Web 应用更加高效。

随着不断学习,我将更深入地探索 Next.js 的高级特性和最佳实践。