技术4 min read
Next.js App Router 入门指南
什么是 App Router?
Next.js 13 引入了全新的 App Router,它基于 React Server Components 构建,带来了更好的性能和开发体验。
App Router 是 Next.js 的未来方向,它提供了更灵活的路由系统、更好的布局支持,以及更高效的渲染方式。
目录结构
App Router 使用 app 目录来组织路由:
app/
├── layout.tsx # 根布局
├── page.tsx # 首页
├── about/
│ └── page.tsx # 关于页面
├── blog/
│ ├── page.tsx # 博客列表
│ └── [slug]/
│ └── page.tsx # 博客详情
└── api/
└── route.ts # API 路由
关键特性
1. 服务端组件
默认情况下,App Router 中的组件是服务端组件。这意味着它们在服务器上渲染,减少了客户端 JavaScript 的大小。
// 这是一个服务端组件(默认)
export default async function ServerComponent() {
const data = await fetch('https://api.example.com/data');
const posts = await data.json();
return (
<div>
{posts.map(post => (
<article key={post.id}>
<h2>{post.title}</h2>
<p>{post.excerpt}</p>
</article>
))}
</div>
);
}
2. 客户端组件
需要交互的组件需要添加 'use client' 指令:
'use client';
import { useState } from 'react';
export default function Counter() {
const [count, setCount] = useState(0);
return (
<div>
<p>当前计数: {count}</p>
<button onClick={() => setCount(count + 1)}>
增加
</button>
<button onClick={() => setCount(0)}>
重置
</button>
</div>
);
}
3. 布局系统
布局在导航时不会重新渲染,这使得状态保持成为可能:
// app/layout.tsx
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html lang="zh">
<body>
<header>
<nav>导航栏</nav>
</header>
<main>{children}</main>
<footer>页脚</footer>
</body>
</html>
);
}
4. 加载状态
使用 loading.tsx 文件创建加载状态:
// app/blog/loading.tsx
export default function Loading() {
return (
<div className="loading">
<div className="spinner" />
<p>加载中...</p>
</div>
);
}
5. 错误处理
使用 error.tsx 文件处理错误:
'use client';
// app/blog/error.tsx
export default function Error({
error,
reset,
}: {
error: Error & { digest?: string };
reset: () => void;
}) {
return (
<div>
<h2>出错了!</h2>
<p>{error.message}</p>
<button onClick={() => reset()}>重试</button>
</div>
);
}
与 Pages Router 的对比
| 特性 | App Router | Pages Router |
|---|---|---|
| React Server Components | ✅ 支持 | ❌ 不支持 |
| 布局嵌套 | ✅ 原生支持 | ⚠️ 需要自定义 |
| 数据获取 | async/await | getServerSideProps |
| 流式渲染 | ✅ 支持 | ❌ 不支持 |
| 加载状态 | loading.tsx | 自定义实现 |
| 错误处理 | error.tsx | 自定义实现 |
数据获取
App Router 支持在组件中直接获取数据:
// 服务端组件中获取数据
async function getPosts() {
const res = await fetch('https://api.example.com/posts');
if (!res.ok) {
throw new Error('获取文章失败');
}
return res.json();
}
export default async function BlogPage() {
const posts = await getPosts();
return (
<div>
<h1>博客文章</h1>
{posts.map(post => (
<article key={post.id}>
<h2>{post.title}</h2>
<p>{post.content}</p>
</article>
))}
</div>
);
}
总结
App Router 是 Next.js 的未来方向,它提供了更好的性能和更灵活的布局系统。对于新项目,强烈建议使用 App Router。
如果你正在使用 Pages Router,也不必急于迁移。两种路由系统可以共存,你可以逐步将页面迁移到 App Router。
相关资源: