标准答案

  1. Server Component 在服务端渲染,不会把组件代码打进客户端 bundle。
  2. 它可以直接访问数据库、文件系统或服务端 API,但不能使用 useState、useEffect 和浏览器事件。
  3. Client Component 才能处理交互、状态、浏览器 API 和事件监听,需要通过 use client 标记边界。
  4. Server Component 可以把数据和展示更靠近服务端,减少客户端请求瀑布和 bundle 体积。
  5. 传给 Client Component 的 props 必须可序列化,函数、类实例等不能随意跨边界传递。

题目解析

这道题要讲清执行环境。Server Component 不是传统 SSR 的同义词,而是一种组件模型边界。

RSC 适合内容读取、数据聚合和非交互展示,Client Component 适合表单、按钮、弹窗和本地状态。

边界设计不当会让 use client 往上蔓延,最后失去减少客户端 JS 的收益。

代码示例

下面把文章读取留在服务端,把收藏按钮留给客户端组件处理。

TSX
export default async function ArticlePage({ params }: { params: { slug: string } }) {
  const article = await getArticleFromDatabase(params.slug)

  return (
    <article>
      <h1>{article.title}</h1>
      <ArticleBody content={article.content} />
      <FavoriteButton articleId={article.id} />
    </article>
  )
}

常见误区

  • 在 Server Component 里使用 useState、useEffect 或 window。
  • 把页面顶层都标记为 use client,导致服务端组件收益消失。
  • 向 Client Component 传递不可序列化对象,跨边界时出错。

作者信息