·前端开发·4 分钟阅读

Next.js App Router 数据获取:Server Component、缓存与流式渲染

分享X微博

默认就在服务端

App Router 下,未标记 "use client" 的组件默认是 Server Component。可以直接:

  • 读文件系统(如 Markdown 博客)
  • 访问数据库(同 VPC 内网)
  • 调用内部 API,且不暴露密钥
// app/blog/page.tsx — Server Component
import { getAllPosts } from "@/lib/posts";

export default function BlogPage() {
  const posts = getAllPosts(); // 构建时或请求时执行
  return (
    <ul>
      {posts.map((p) => (
        <li key={p.slug}>{p.title}</li>
      ))}
    </ul>
  );
}

fetch 的四种缓存语义

写法行为
fetch(url)默认缓存(静态生成时复用)
fetch(url, { cache: "no-store" })每次请求都打源站
fetch(url, { next: { revalidate: 60 } })ISR:60 秒内用缓存
export const dynamic = "force-dynamic"整页动态

个人博客读本地 Markdown,通常用 构建时静态生成generateStaticParams),无需 no-store

静态路径与动态段

export async function generateStaticParams() {
  return getAllSlugs().map((slug) => ({ slug }));
}

构建阶段为每篇文章生成 HTML,CDN 友好;新文章发布后需 重新 build 或配合 revalidatePath

loading.tsx 与 Suspense

// app/blog/loading.tsx
export default function Loading() {
  return <p className="animate-pulse">加载中…</p>;
}

路由切换时自动展示,适合慢查询;快路径(本地 fs)可省略。

何时用 Client Component

仅在需要以下能力时加 "use client"

  • useState / useEffect
  • 浏览器 API(localStorage、剪贴板)
  • 事件监听(主题切换、搜索框防抖)

数据仍应在 Server Component 拉取,通过 props 下发,避免 瀑布请求

反模式

  1. useEffectfetch('/api/posts') 渲染列表 — 多一轮 RTT
  2. 全站 "use client" — 失去 RSC 体积与 SEO 优势
  3. 混用 Pages Router 的 getServerSideProps 心智 — 改读 App Router 文档

小结

数据靠近数据源、交互靠近浏览器。ZhuBook 博客列表与文章页均在服务端读 content/posts,评论表单才是 Client Component——这是 App Router 的典型切分。

相关阅读

本站评论 (0)

  • 暂无评论,来说第一句吧。