跳到主要内容

Server Components

  • 页面和布局默认是 Server Components。官方说明里明确提到:默认的 layouts 和 pages 是 Server Components
  • 默认优先 Server Component,只有需要交互、浏览器 API、客户端状态时才切到 Client Component

server component和ssr​

  • Server Component 是“组件类型”,SSR 是“渲染方式”
  • Server Components 定义为一种在独立服务器环境中运行的组件;而 Next.js 对 SSR 的定义是:每次请求都在服务器上生成页面 HTM

Server Components vs Client Component​

Server Component​

运行在服务端,特点:

  • 可以直接访问服务端资源
  • 可以在组件里直接获取数据
  • 不会把服务端逻辑和敏感信息发到客户端
  • 输出是渲染结果和 RSC payload
  • 更有利于减少客户端 JS 体积

为什么说 Server Component 有利于性能?

  1. 不会把组件逻辑直接打到客户端 bundle
  2. 可以在服务端直接获取数据
  3. 可以在服务端利用缓存
  4. 可以避免把敏感逻辑暴露给浏览器

Client Component​

需要在文件顶部写:

text
'use client'

特点:

  • 可以使用 useState、useEffect
  • 可以使用浏览器 API
  • 可以绑定点击事件等交互
  • 会进入客户端 bundle

混合使用 Server Components、 Client Component、 SSR​

  • 页面本身默认就是 Server Component
  • 页面的数据是动态请求的数据,这里就是SSR
  • 交互部分拆成 Client Component,嵌进 Server Component 页面
tsx
// app/users/SearchBox.tsx
'use client'

import { useState } from 'react'

export default function SearchBox() {
const [keyword, setKeyword] = useState('')

return (
<input
value={keyword}
onChange={(e) => setKeyword(e.target.value)}
placeholder="搜索用户"
/>
)
}
  • page.tsx
    • page.tsx 是 Server Component
    • fetch(..., { cache: 'no-store' }) 或 dynamic = 'force-dynamic' 会让页面按请求动态渲染,也就是 SSR
    • export const dynamic = 'force-dynamic' , 强制这个路由段按“请求时动态渲染”处理,而不是静态预渲染
tsx
// app/users/page.tsx
import SearchBox from './SearchBox'

export const dynamic = 'force-dynamic'

async function getUsers() {
const res = await fetch('https://api.example.com/users', {
cache: 'no-store',
})
return res.json()
}

export default async function UsersPage() {
const users = await getUsers()

return (
<div>
<SearchBox />
<ul>
{users.map((user: any) => (
<li key={user.id}>{user.name}</li>
))}
</ul>
</div>
)
}