为什么选择 Next.js 14?
Next.js 14 引入了稳定的 App Router,通过 Server Component、React Suspense 和 Server Actions 重新定义了 React 应用的开发范式。
1. App Router 目录结构
app/
├── layout.tsx # 根布局
├── page.tsx # 首页
├── loading.tsx # 加载状态
├── error.tsx # 错误边界
├── not-found.tsx # 404 页面
├── blog/
│ ├── page.tsx # /blog
│ └── [slug]/
│ └── page.tsx # /blog/:slug
└── api/
└── posts/
└── route.ts # /api/posts
2. Server Component vs Client Component
// app/page.tsx - 默认是 Server Component
// 可以直接访问数据库、文件系统,无需 API 层
import { db } from '@/lib/db';
export default async function HomePage() {
const posts = await db.post.findMany({ take: 10 });
return (
<main>
{posts.map(post => (
<PostCard key={post.id} post={post} />
))}
</main>
);
}
// components/PostCard.tsx - Client Component
'use client';
export function PostCard({ post }) {
const [liked, setLiked] = useState(false);
return (
<div onClick={() => setLiked(!liked)}>
{post.title} {liked ? '❤' : '♡'}
</div>
);
}
3. Streaming SSR 与 Suspense
// app/page.tsx - 流式渲染
import { Suspense } from 'react';
import { PostList, PostListSkeleton } from '@/components/posts';
import { Sidebar, SidebarSkeleton } from '@/components/sidebar';
export default function Page() {
return (
<div className="flex gap-8">
<Suspense fallback={<PostListSkeleton />}>
<PostList /> // 先渲染骨架屏,数据到达后流式替换
</Suspense>
<Suspense fallback={<SidebarSkeleton />}>
<Sidebar />
</Suspense>
</div>
);
}
4. Server Actions(表单处理)
// app/actions.ts
'use server';
import { revalidatePath } from 'next/cache';
export async function createPost(formData: FormData) {
const title = formData.get('title') as string;
await db.post.create({ data: { title } });
revalidatePath('/posts'); // 重新验证缓存
}
// components/NewPost.tsx
export function NewPost() {
return (
<form action={createPost}>
<input name="title" />
<button type="submit">发布</button>
</form>
);
}
总结
Next.js 14 的 App Router 提供了原生全栈开发能力。Server Component 减少客户端 JavaScript,Streaming SSR 优化首屏体验,Server Actions 简化数据变更流程。