主题
07 · 数据获取、缓存与重新验证
目标:在 Server Component 里用
fetch取数;建立 cache / revalidate 的直觉,少在客户端useEffect里扛首屏。
官方主文:Data Fetching, Caching, and Revalidating · Caching(版本若改版,以 docs 侧栏「Data Fetching」为准)
1. 默认姿势:Server 上取,直接渲染
tsx
// app/posts/page.tsx — Server Component
async function getPosts() {
const res = await fetch('https://jsonplaceholder.typicode.com/posts?_limit=5', {
// 示例:一段时间后重新验证(秒)
next: { revalidate: 60 },
})
if (!res.ok) throw new Error('Failed to fetch')
return res.json() as Promise<{ id: number; title: string }[]>
}
export default async function PostsPage() {
const posts = await getPosts()
return (
<main style={{ padding: 24 }}>
<h1>Posts</h1>
<ul>
{posts.map((p) => (
<li key={p.id}>{p.title}</li>
))}
</ul>
</main>
)
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
访问 /posts。失败时可配合 05 的 error.tsx。
对照 Journal:以前「Koa 返回 JSON → 前端 onMounted fetch」;App Router 常见路径是「Server 取数 → 直接出 HTML/RSC」,浏览器少一轮瀑布。
2. 缓存直觉(先建立模型,细节以官方为准)
不同 Next 大版本对「fetch 默认是否缓存」有过调整——以你安装版本的官方 Data Fetching 页为准。学习期记住三类旋钮:
| 意图 | 常见写法(查阅官方确认) |
|---|---|
| 一段时间新鲜即可 | next: { revalidate: N } |
| 每次请求都最新 | cache: 'no-store' 或文档中的动态等价选项 |
| 按标签失效 | next: { tags: ['notes'] } + 之后 revalidateTag(写操作篇会用到) |
不要死背博客里的「Next 默认一定缓存/一定不缓存」——打开你本机对应版本文档核对。
3. 并行与瀑布
tsx
// 好:并行
const [a, b] = await Promise.all([getA(), getB()])
// 差:无依赖却串行 await getA(); await getB();1
2
3
4
2
3
4
官方鼓励在 Server 组件里并行取数;可用 loading.tsx 提升感知速度。
4. 何时仍在客户端取数
| 场景 | 做法 |
|---|---|
| 强依赖浏览器手势后的搜索(防抖) | Client fetch / 后续再引入库 |
| 用户专属、且必须客户端会话的数据 | 仍可优先 Route Handler + Server;或 Client |
| 首屏公开列表 | 优先 Server fetch(本篇) |
本系列小项目(10)用本地 JSON 文件,不依赖外网 API;本篇用公开 API 只为练 fetch 与缓存旋钮。
5. 与 Effect 的边界(呼应 04)
| 做法 | 评价 |
|---|---|
Server async + fetch 首屏 | 推荐 |
Client useEffect + fetch 扛首屏列表 | 能跑,但易瀑布、难 SEO、重复劳动;先问能否 Server |
| Effect 里 setState 同步 props | 仍按 04,通常不需要 |
6. 必做验收
- [ ]
/posts能列出若干标题 - [ ] 打开官方 Data Fetching 页,对照你用的
revalidate/no-store含义 - [ ] 能向别人说清:为什么首屏列表优先 Server,而不是
useEffect - [ ] (可选)给
app/posts/loading.tsx加一句「加载中」
7. AI 提示词约束(本篇)
text
技术约束:Next.js App Router;在 Server Component 中 fetch。
请根据我粘贴的 next 版本,引用官方文档说明
当前 fetch 缓存默认行为,并给出列表页最小实现。
禁止默认改成 React Query,除非我明确要求。1
2
3
4
2
3
4
