在 App Router 中,你可以直接在 async Server Components 内使用标准 fetch API 获取数据 — 无需 getServerSideProps、无需 useEffect、无需单独的数据层。Next.js 扩展了 fetch 以支持缓存控制。
// app/posts/page.tsx — a Server Component
export default async function Posts() {
const res = await fetch("https://api.example.com/posts"); // runs on the server
const posts = await res.json();
return <ul>{posts.map(p => <li key={p.id}>{p.title}</li>)}</ul>;
}
因为组件运行在服务器上,你只需简单地 await 你的数据并使用它 — 比客户端 useEffect + useState + loading 状态的方式简洁得多。
Next.js 增强了 fetch,使得每个调用都能选择其渲染行为:
fetch(url, { cache: "force-cache" }); // SSG — cached (default for static)
fetch(url, { cache: "no-store" }); // SSR — fresh every request
fetch(url, { next: { revalidate: 60 } }); // ISR — revalidate every 60s
fetch(url, { next: { tags: ["posts"] } }); // tag for on-demand revalidation
这是 App Router 的统一模型:你不再选择页面级策略,而是在数据获取级别控制缓存。
// ❌ sequential — each awaits the previous (slow waterfall)
const user = await getUser();
const posts = await getPosts();
// ✅ parallel — both start at once
const [user, posts] = await Promise.all([getUser(), getPosts()]);
使用 Promise.all 一起启动独立请求,以防止它们相互阻塞。
"use client";
// for client-side data (e.g. after interaction), use a library like SWR or React Query
const { data } = useSWR("/api/user", fetcher);
Server Components 涵盖了大多数需求;对于客户端、交互式或频繁重新验证的数据,请使用 SWR/React Query。
Next.js 自动去重单次渲染中的相同 fetch 调用 — 因此你可以在布局和页面中获取相同数据,而不会产生重复请求。
在 Server Components 中直接进行异步数据获取是 App Router 最大的简化之一 — 无需样板代码、安全的服务器端访问、自动去重,以及充当你的 SSG/SSR/ISR 选择的按 fetch 级别缓存。
了解如何并行化独立 fetch(避免瀑布流)是关键的性能实践。