tech
2024年01月02日
4 分钟阅读
Next.js App Router 深度解析
Next.jsReactApp Router前端开发
Next.js App Router 深度解析
Next.js 13 引入了全新的 App Router,这是一个基于 React Server Components 的新路由系统。本文将深入探讨 App Router 的核心特性和使用方法。
什么是 App Router?
App Router 是 Next.js 13+ 版本中的新路由系统,它提供了:
- 基于文件系统的路由
- 支持 React Server Components
- 改进的性能和开发体验
- 更好的 SEO 支持
文件结构
App Router 使用 app 目录来组织路由:
app/
├── page.tsx # 根路由 (/)
├── layout.tsx # 根布局
├── loading.tsx # 加载状态
├── error.tsx # 错误页面
├── not-found.tsx # 404 页面
├── posts/
│ ├── page.tsx # /posts
│ ├── [slug]/
│ │ └── page.tsx # /posts/[slug]
│ └── layout.tsx # posts 布局
└── about/
└── page.tsx # /about
核心特性
1. 服务器组件 (Server Components)
默认情况下,App Router 中的组件都是服务器组件:
// app/posts/page.tsx
import { getAllPosts } from '@/lib/posts'
export default async function PostsPage() {
const posts = await getAllPosts()
return (
<div>
<h1>所有文章</h1>
{posts.map(post => (
<div key={post.id}>{post.title}</div>
))}
</div>
)
}
2. 客户端组件 (Client Components)
使用 'use client' 指令创建客户端组件:
'use client'
import { useState } from 'react'
export default function SubscriptionForm() {
const [email, setEmail] = useState('')
return (
<form>
<input
value={email}
onChange={(e) => setEmail(e.target.value)}
placeholder="输入邮箱"
/>
<button type="submit">订阅</button>
</form>
)
}
3. 布局系统
布局可以嵌套,为不同路由提供共享的 UI:
// app/layout.tsx (根布局)
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html lang="zh-CN">
<body>
<Header />
<main>{children}</main>
<Footer />
</body>
</html>
)
}
4. 数据获取
App Router 简化了数据获取:
// 服务器组件中直接使用 async/await
export default async function PostPage({ params }: { params: { slug: string } }) {
const post = await getPost(params.slug)
return (
<article>
<h1>{post.title}</h1>
<p>{post.content}</p>
</article>
)
}
性能优化
1. 静态生成
// 生成静态参数
export async function generateStaticParams() {
const posts = await getAllPosts()
return posts.map(post => ({ slug: post.slug }))
}
2. 元数据管理
export async function generateMetadata({ params }: { params: { slug: string } }) {
const post = await getPost(params.slug)
return {
title: post.title,
description: post.excerpt,
openGraph: {
title: post.title,
description: post.excerpt,
type: 'article',
},
}
}
3. 流式渲染
使用 loading.tsx 实现流式渲染:
// app/posts/loading.tsx
export default function Loading() {
return <div>加载中...</div>
}
最佳实践
1. 组件分离
- 服务器组件:数据获取、静态内容
- 客户端组件:交互功能、状态管理
2. 错误处理
// app/error.tsx
'use client'
export default function Error({
error,
reset,
}: {
error: Error
reset: () => void
}) {
return (
<div>
<h2>出错了!</h2>
<button onClick={() => reset()}>重试</button>
</div>
)
}
3. 路由组织
- 使用文件夹组织相关路由
- 利用
layout.tsx共享布局 - 适当使用路由组
(group)
迁移建议
从 Pages Router 迁移到 App Router:
- 逐步迁移,两个系统可以共存
- 先迁移简单的静态页面
- 处理数据获取逻辑的变化
- 更新客户端组件的使用方式
总结
App Router 为 Next.js 带来了:
- 更好的性能:服务器组件减少了客户端 JavaScript
- 更简单的数据获取:直接在组件中使用 async/await
- 更好的开发体验:改进的错误处理和加载状态
- 更强的 SEO 支持:更好的流式渲染和元数据管理
App Router 是 Next.js 的未来,值得深入学习和使用。
本文介绍了 Next.js App Router 的核心特性和使用方法,希望对你的开发工作有所帮助!